package org.jsola.hr.service.impl;

import cn.hutool.core.date.DateField;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Validator;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileItemFactory;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.session.RowBounds;
import org.apache.poi.ss.usermodel.IndexedColors;
import org.jsola.admin.dto.DictItemUpdateDTO;
import org.jsola.admin.entity.DictItemDO;
import org.jsola.admin.entity.SiteDO;
import org.jsola.admin.vo.*;
import org.jsola.approval.constant.ApproType;
import org.jsola.approval.dto.NewApproDTO;
import org.jsola.approval.query.UserApproQuery;
import org.jsola.approval.service.IUserApproService;
import org.jsola.approval.vo.ApproFlowListVO;
import org.jsola.approval.vo.UserApproListVO;
import org.jsola.approval.vo.UserApproVO;
import org.jsola.cache.ICache;
import org.jsola.common.*;
import org.jsola.contract.constant.FileType;
import org.jsola.contract.entity.ContractDO;
import org.jsola.contract.entity.TemplateDO;
import org.jsola.contract.vo.CategoryVO;
import org.jsola.core.Page;
import org.jsola.core.entity.BaseDO;
import org.jsola.exception.ParamException;
import org.jsola.hr.common.*;
import org.jsola.hr.constant.*;
import org.jsola.hr.dao.IEmpInfoDAO;
import org.jsola.hr.dto.*;
import org.jsola.hr.dto.excel.EmpInfoImportDTO;
import org.jsola.hr.entity.*;
import org.jsola.hr.entity.salary.HourAmountRule;
import org.jsola.hr.entity.salary.LeaveOfficeRule;
import org.jsola.hr.entity.salary.RedPacketRule;
import org.jsola.hr.example.PersonalEventExample;
import org.jsola.hr.exception.HrException;
import org.jsola.hr.provider.*;
import org.jsola.hr.query.*;
import org.jsola.hr.service.*;
import org.jsola.hr.service.async.IAsyncEmpInfoDetailService;
import org.jsola.hr.service.async.IAsyncEmpInfoImportService;
import org.jsola.hr.service.excel.EmpInfoImportListener;
import org.jsola.hr.service.excel.EmpInfoImportZhiXinRenBySiteListener;
import org.jsola.hr.service.excel.EmpInfoImportZhiXinRenListener;
import org.jsola.hr.service.notice.ISendNoticeService;
import org.jsola.hr.task.SendNoticeTask;
import org.jsola.hr.vo.*;
import org.jsola.hr.vo.CustomTemplateFieldVO;
import org.jsola.hr.vo.CustomTemplateVO;
import org.jsola.hr.vo.excel.ParseResultVO;
import org.jsola.json.JsonKit;
import org.jsola.message.dto.ShortMessageDTO;
import org.jsola.notice.constant.NoticeConstants;
import org.jsola.notice.constant.ReceiveDateTypeEnum;
import org.jsola.notice.vo.NoticeRuleSettingVO;
import org.jsola.orm.filter.Order;
import org.jsola.salary.entity.ChannelFeeSettlementDetailDO;
import org.jsola.salary.entity.EmpFixedSalaryDO;
import org.jsola.salary.entity.EmpTaxGrandTotalDO;
import org.jsola.salary.entity.SpecialAdditionalDetailDO;
import org.jsola.salary.vo.WorkTimeVO;
import org.jsola.user.common.PinyinKit;
import org.jsola.user.common.UserCacheKeyKit;
import org.jsola.user.core.TokenUser;
import org.jsola.user.core.UserContext;
import org.jsola.user.dto.UpdateByPhoneDTO;
import org.jsola.user.entity.ThirdInfoDO;
import org.jsola.user.entity.UserDO;
import org.jsola.user.service.IThirdInfoService;
import org.jsola.user.vo.UserVO;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.commons.CommonsMultipartFile;
import tk.mybatis.mapper.entity.Example;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.lang.reflect.Field;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.concurrent.Future;
import java.util.function.Function;
import java.util.stream.Collectors;

import static org.jsola.contract.constant.ContractConstants.SIGN_CONFIRM_DATE_REPLACE;
import static org.jsola.hr.constant.EmpInfoStatus.*;
import static org.jsola.hr.constant.EmpSocStatus.*;
import static org.jsola.hr.constant.FormalTypeEnum.FORMAL;
import static org.jsola.hr.constant.FormalTypeEnum.PROBATION;
import static org.jsola.hr.constant.HrConstants.JIA_FANG_QY;
import static org.jsola.hr.constant.HrConstants.JIA_FANG_SY;
import static org.jsola.hr.constant.HrPermissionConstants.*;
import static org.jsola.hr.service.impl.CompanyNecessaryFieldServiceImpl.POST_TYPE;

/**
 * 员工信息
 *
 * @author zhr
 */
@Service("hrEmpInfoServiceImpl")
@Slf4j
public class EmpInfoServiceImpl implements IEmpInfoService {

    @Autowired
    private IEmpInfoDAO empInfoDAO;

    @Autowired
    private IEmpCardService empCardService;

    @Autowired
    private IEmpWorkService empWorkService;

    @Autowired
    private IEmpContactsService empContactsService;

    @Autowired
    private IEmpContractService empContractService;

    @Autowired
    private IEmpEducationService empEducationService;

    @Autowired
    private IEmpTrainService empTrainService;

    @Autowired
    private IEmpCertificateService empCertificateService;

    @Autowired
    private IDepInfoService depInfoService;

    @Autowired
    private IPositionInfoService positionInfoService;

    @Autowired
    private IEmpDepService empDepService;

    @Autowired
    private IEmpPositionService empPositionService;

    @Autowired
    private IApproProviderService approProviderService;

    @Autowired
    private IEmpChangesService empChangesService;

    @Autowired
    private IContractProviderService contractProviderService;

    @Autowired
    private IUserProviderService userProviderService;

    @Autowired
    private IPermissionProviderService permissionProviderService;

    @Autowired
    private ICompanyService companyService;

    @Autowired
    private IGroupCompanyService groupCompanyService;

    @Autowired
    private IEmpSocInfoService empSocInfoService;

    @Autowired
    private IEmpSocMonthService empSocMonthService;

    @Autowired
    private IEmpFamilyService empFamilyService;

    @Autowired
    private IEmpRewardPunishService empRewardPunishService;

    @Autowired
    private IHrPermissionService hrPermissionService;

    @Autowired
    private IAdminProviderService adminProviderService;

    @Autowired
    private IMessageProviderService messageProviderService;

    @Autowired
    private ICompanyEmpNecessaryService companyEmpNecessaryService;

    @Autowired
    private IThirdInfoService thirdInfoService;

    @Autowired
    private ICompanyNecessaryFieldService companyNecessaryFieldService;

    @Autowired
    private IEmpPaperContractService empPaperContractService;

    @Autowired
    private ICompanyAdditionalFieldsService companyAdditionalFieldsService;

    @Autowired
    private IPersonalEventService personalEventService;

    @Lazy
    @Autowired
    private IEmpAdditionalFieldsService empAdditionalFieldsService;

    @Lazy
    @Autowired
    private IStatisticsPageService statisticsPageService;

    @Autowired
    private ISiteConfigProviderService siteConfigProviderService;

    @Autowired
    private ISalaryCalculateRuleService salaryCalculateRuleService;

    @Autowired
    private ICheckInPeopleService checkInPeopleService;

    @Autowired
    private ISalaryProviderService salaryProviderService;

    @Autowired
    private IChannelService channelService;

    @Autowired
    private ISocProgService socProgService;

    @Autowired
    private ICache cache;

    @Autowired
    private IFileProviderService fileProviderService;

    @Autowired
    private IEmpTagService empTagService;

    @Autowired
    private IOperationEmpRecordService operationEmpRecordService;

    @Autowired
    @Lazy
    private IChildCompanyService childCompanyService;

    @Autowired
    private SendNoticeTask sendNoticeTask;

    @Autowired
    private IEmpSocRelatedService empSocRelatedService;

    @Autowired
    private IOnJobRecordService onJobRecordService;

    @Autowired
    private ISalaryCalculateRuleGroupService salaryCalculateRuleGroupService;

    @Autowired
    private ITransferAccountInfoService transferAccountInfoService;

    @Autowired
    private IUserApproService userApproService;

    @Autowired
    private ISendNoticeService sendNoticeService;

    @Autowired
    private INoticeProviderService noticeProviderService;

    @Autowired
    private INameVerifiedService nameVerifiedService;

    @Autowired
    private IAsyncEmpInfoImportService asyncEmpInfoImportService;

    @Autowired
    private IAsyncEmpInfoDetailService asyncEmpInfoDetailService;

    @Autowired
    private ICustomTemplateService customTemplateService;

    @Autowired
    private IEmpFamilyService familyService;

    @Autowired
    private IEmpContactsService contactsService;


    @Autowired
    private RedissonClient redissonClient;

    private static final String DATE_STR = "class java.util.Date";
    /**
     * 国籍(地区), 默认中国
     */
    private static final String NATIONALITY = "中国";
    /**
     * 任职受雇从业类型(默认1:雇员)
     */
    private static final String EMPLOYMENT_TYPE = "1";

    /**
     * 待入职
     */
    private static final Integer PENDING_RELATION = 1;
    /**
     * 审批中
     */
    private static final Integer APPROVING = 2;
    /**
     * 审批驳回
     */
    private static final Integer REFUSE = 3;
    /**
     * 未到岗
     */
    private static final Integer NO_ARRIVAL = 4;

    /**
     * 员工最大标签数量
     */
    private static final Integer MAX_TAG_COUNT = 6;

    /**
     * 标签sql字段
     */
    private static final String SQL_TAG = "tag";

    /**
     * 自定义字段类型-地区
     */
    private static final Integer FIELD_TYPE_AREA = 6;

    /**
     * 花名册模块code
     */
    private static final String EMP_INFO_BY_COMPANY = "empInfoByCompany";

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoVO save(EmpInfoAddDTO empInfoAddDTO, TokenUser tokenUser) {
        // 转DO
        EmpInfoDO empInfoDO = empInfoAddDTO.to(EmpInfoDO.class);

        // 校验公司下是否有相同手机号
        EmpInfoVO empInfoVO = selectByPhone(empInfoAddDTO.getCompanyId(), empInfoAddDTO.getPhone(), tokenUser.getSiteId());
        if (!Objects.isNull(empInfoVO)) {
            throw new ParamException("公司下已存在手机号为'" + empInfoAddDTO.getPhone() + "'的员工");
        }
        EmpInfoDO empInfoDO1 = selectEmpByIdCard(empInfoAddDTO.getCompanyId(), empInfoAddDTO.getIdCard(), tokenUser);
        if (!Objects.isNull(empInfoDO1)) {
            throw new ParamException("公司下已存在身份证号为'" + empInfoAddDTO.getIdCard() + "'的员工");
        }
        // 校验手机号是否已入职其他公司
        checkByPhone(empInfoAddDTO.getPhone(), tokenUser.getSiteId(), tokenUser);

        if (empInfoDO.getEmployType() == null) {
            // 聘用形式（0：非正式，1：正式）
            empInfoDO.setEmployType(true);
        }

        if (PROBATION.getValue().equals(empInfoAddDTO.getFormalType())) {
            // 正式类型/入职时间/试用天数/转正天数的处理
            checkEmpProbationAndFormal(true, empInfoDO, tokenUser);
        }
        // 校验标签数量
        checkTag(empInfoAddDTO.getTag());

        if (empInfoDO.getContractsStatus() == null) {
            // 合同状态（0:合同未发起;1:待员工签署;2:带公司签署;3:签署完成）
            empInfoDO.setContractsStatus(0);
        }
        if (empInfoDO.getJoinFormStatus() == null) {
            // 入职登记表状态（0：未提交，1：已提交）
            empInfoDO.setJoinFormStatus(false);
        }
        if (empInfoDO.getChangeStatus() == null) {
            // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
            empInfoDO.setChangeStatus(0);
        }
        if (empInfoDO.getStatus() == null) {
            // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
            empInfoDO.setStatus(1);
        }
        if (empInfoDO.getApprovalStatus() == null) {
            // 审批状态（1：待审批，2：审批中，3：审批未通过，4：审批已通过，5：不需要审批）
            empInfoDO.setApprovalStatus(5);
        }
        if (empInfoDO.getPostType() == null) {
            // 岗位类型
            empInfoDO.setPostType(PostType.OTHER.getValue());
        }
        if (empInfoDO.getVerified() == null) {
            //实名认证
            empInfoDO.setVerified(false);
        }
        if (empInfoDO.getEmpSocStatus() == null) {
            //实名认证
            empInfoDO.setEmpSocStatus(NOT_SOC.getValue());
        }
        if (empInfoDO.getIdCard() != null) {
            String idCard = empInfoDO.getIdCard();
            if (RegUtils.isIdCard(idCard)) {
                // 拿身份证号辨别性别,年龄,身份证号
                if (empInfoDO.getIdCard().length() == 18) {
                    empInfoDO.setGender(Integer.parseInt(idCard.substring(16, 17)) % 2 == 0 ? 2 : 1);
                    empInfoDO.setBirthday(idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14) + " 00:00:00");
                    empInfoDO.setEmpAge(DateUtils.getYearDiff(DateUtil.parse(empInfoDO.getBirthday()), new Date(System.currentTimeMillis())));
                } else if (empInfoDO.getIdCard().length() == 15) {
                    empInfoDO.setGender(Integer.parseInt(idCard.substring(13, 14)) % 2 == 0 ? 2 : 1);
                    empInfoDO.setBirthday("19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12) + " 00:00:00");
                    empInfoDO.setEmpAge(DateUtils.getYearDiff(DateKit8.parseDateTime(empInfoDO.getBirthday()), new Date(System.currentTimeMillis())));
                }
                empInfoDO.setCertificateType(CertificateTypeEnum.ID_CARD.getValue());
            } else if (RegUtils.isHMCard(idCard)) {
                empInfoDO.setCertificateType(CertificateTypeEnum.HM_CARD.getValue());
            } else if (RegUtils.isTWCard(idCard)) {
                empInfoDO.setCertificateType(CertificateTypeEnum.TW_CARD.getValue());
            } else {
                throw new ParamException("身份证格式错误");
            }
        }

        //名字拼音补全
        empInfoDO.setNamePinyin(PinyinKit.nameToPinyin(empInfoDO.getName()));
        // 证件类型(默认1:居民身份证)
        if (empInfoDO.getCertificateType() == null) {
            empInfoDO.setCertificateType(CertificateTypeEnum.ID_CARD.getValue());
        }
        // 国籍(地区), 默认中国
        if (empInfoDO.getNationality() == null) {
            empInfoDO.setNationality(NATIONALITY);
        }
        // 任职受雇从业类型(默认1:雇员)
        if (empInfoDO.getEmploymentType() == null) {
            empInfoDO.setEmploymentType(EMPLOYMENT_TYPE);
        }

        // 社保代缴按正式员工处理
        if (empInfoDO.getPostType().equals(PostType.SOCIAL_SECURITY_PAYMENT.getValue())) {
            empInfoDO.setFormalType(2);
        }
        // 保存
        empInfoDO = save(empInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
        //因为现在直接跳过确认到岗流程,需要在添加员工时直接把岗位和部门添加到empdep表中
        //加入确认到岗流程后这段代码删掉
        // 加入员工部门/岗位
        // 部门ID列表
        /*if (!StringUtils.isEmpty(empInfoDO.getPreJoinDep())) {
            String[] depIdList = empInfoDO.getPreJoinDep().split(",");
            publishEmpDep(Arrays.asList(depIdList), empInfoDO.getCompanyId(), empInfoDO.getId(), tokenUser);

        }*/
        // 岗位ID列表
        /*if (!StringUtils.isEmpty(empInfoDO.getPreJoinPosition())) {
            String[] positionIdList = empInfoDO.getPreJoinPosition().split(",");
            publishEmpPosition(Arrays.asList(positionIdList), empInfoDO.getCompanyId(), empInfoDO.getId(), tokenUser);

        }*/
        //保存后记录人事变动表 系统自动添加
        //String desc = PersonalEventExample.INSERT_INTO_ADMIN +tokenUser.getUserName()+PersonalEventExample.INSERT_INTO_SYS;
        //personalEventService.autoSave(empInfoDO.to(EmpInfoVO.class),tokenUser,desc,PersonalEventEnum.ADD.getValue(),PersonalEventEnum.ADD.getDesc());
        sendNotice(empInfoDO, tokenUser);
        return empInfoDO.to(EmpInfoVO.class);
    }

    /**
     * 添加待入职/入职员工发通知
     *
     * @param runDate   运行时间
     * @param type      发送通知类型 2为入职通知 1为入职和待转正通知
     * @param subjectId 业务id
     * @param companyId 用工单位id
     * @param tokenUser 当前用户
     */
    private void sendNotice(Date runDate, Integer type, String subjectId, String companyId, TokenUser tokenUser) {
        try {
            // 添加入职员工
            if (type.equals(FORMAL.getValue())) {
                sendNoticeTask.addTask(subjectId, NoticeConstants.INDUCTION, companyId,
                        runDate, "人员入职发送通知", tokenUser);
            } else if (type.equals(PROBATION.getValue())) {
                sendNoticeTask.addTask(subjectId, NoticeConstants.PRE_TURN_OFFICIAL, companyId,
                        runDate, "人员待转正发送通知", tokenUser);
            }
        } catch (Exception e) {
            log.error("添加入职员工发通知失败，错误信息：{}", e.getMessage());
        }
    }

    /**
     * 添加待入职/入职员工发通知
     *
     * @param empInfoDO 员工信息
     * @param tokenUser 当前用户
     */
    @Override
    public void sendNotice(EmpInfoDO empInfoDO, TokenUser tokenUser) {
        try {
            // 添加待入职员工
            if (WAIT_ENTRY.getValue().equals(empInfoDO.getStatus())) {
                //没有待入职审批模板才发送通知
                EmpAllInfoAddDTO empAllInfoAddDTO = empInfoDO.to(EmpAllInfoAddDTO.class);
                checkAppro(empAllInfoAddDTO, tokenUser);
                if (StringUtils.isEmpty(empAllInfoAddDTO.getFlowId())) {
                    sendNoticeTask.addTask(empInfoDO.getId(), NoticeConstants.PRE_INDUCTION, empInfoDO.getCompanyId(),
                            empInfoDO.getJoinDate(), "人员待入职发送通知", tokenUser);
                }
                //List<UserApproListVO> userApproListVOS = empApproList(empInfoDO.getId(), HrConstants.SUBJECT_TYPE_HR_ON_JOB, tokenUser);
//                if(CollectionUtils.isEmpty(userApproListVOS)){
//                    sendNoticeTask.addTask(empInfoDO.getId(), NoticeConstants.PRE_INDUCTION, empInfoDO.getCompanyId(),
//                            empInfoDO.getJoinDate(), "人员待入职发送通知", tokenUser);
//                }
            }
            // 添加入职员工
            else if (HAS_ENTRY.getValue().equals(empInfoDO.getStatus())) {
                // 试用时添加待转正通知
                if (PROBATION.getValue().equals(empInfoDO.getFormalType())) {
                    //没有待审批的转正审批才发送待转正通知
                    List<UserApproListVO> userApproListVOS = empApproList(empInfoDO.getId(), HrConstants.APPROVE_TURN_STRAIGHT, tokenUser);
                    if (CollectionUtils.isEmpty(userApproListVOS)) {
                        sendNoticeTask.addTask(empInfoDO.getId(), NoticeConstants.PRE_TURN_OFFICIAL, empInfoDO.getCompanyId(),
                                empInfoDO.getTurnStraightDate(), "人员待转正发送通知", tokenUser);
                    }
                }
                sendNoticeTask.addTask(empInfoDO.getId(), NoticeConstants.INDUCTION, empInfoDO.getCompanyId(),
                        DateUtil.offsetMinute(new Date(), 1), "人员入职发送通知", tokenUser);
            }
        } catch (Exception e) {
            log.error("添加待入职/入职员工发通知失败，错误信息：{}", e.getMessage());
        }
    }

    @Override
    public List<UserApproListVO> empApproList(String empInfoId, String subjectType, TokenUser tokenUser) {
        UserApproQuery userApproQuery = new UserApproQuery();
        userApproQuery.setSubjectId(empInfoId);
        userApproQuery.setSubjectType(subjectType);
        List<UserApproListVO> approList = userApproService.select(userApproQuery, tokenUser.getSiteId());
        return approList.stream().filter(userapproVO -> userapproVO.getStatus() < 2).collect(Collectors.toList());
    }


    /**
     * 校验标签数量
     */
    private void checkTag(String tag) {
        if (StrKit.isNotEmpty(tag)) {
            String[] array = tag.split(",");
            List<String> tagList = Arrays.asList(array);
            if (tagList.size() > MAX_TAG_COUNT) {
                throw new ParamException("员工最多添加6个标签");
            }
        }
    }

    /**
     * 正式类型/入职时间/试用天数/转正天数的处理
     *
     * @param isAdd     是否是新增,true:新增;false:修改
     * @param empInfoDO 员工信息
     */
    private void checkEmpProbationAndFormal(boolean isAdd, EmpInfoDO empInfoDO, TokenUser tokenUser) {
        if (empInfoDO.getFormalType() == null
                && empInfoDO.getJoinDate() == null
                && empInfoDO.getTurnStraightDate() == null) {
            // 啥都没有,新增默认无状态,修改不做改变返回
            if (isAdd) {
                // 正式类型（0:无状态,1：试用期，2：已转正）
                empInfoDO.setFormalType(FormalTypeEnum.FORMAL.getValue());
            }
            return;
        }

        // 入职时间
        Date joinDate = empInfoDO.getJoinDate();
        // 转正时间
        Date turnStraightDate = empInfoDO.getTurnStraightDate();
        // 试用天数
        Integer probationDays = empInfoDO.getProbationDays();

        if (turnStraightDate == null) {
            // 没有转正时间
            if (joinDate != null) {
                ParamException.notNull(probationDays, "员工只有入职日期,是试用期,试用期请选择试用天数");
                // 根据入职时间和试用天数计算下转正时间
                turnStraightDate = org.apache.commons.lang3.time.DateUtils.addDays(empInfoDO.getJoinDate(), empInfoDO.getProbationDays());
            } else {
                // 既无入职时间,也无转正时间,正式类型无,返回
                empInfoDO.setFormalType(FormalTypeEnum.FORMAL.getValue());
                return;
            }
        }
        // 有入职时间和转正时间中一个,就算在职
        //empInfoDO.setStatus(EmpInfoStatus.HAS_ENTRY.getValue());
        if (joinDate != null) {
            // 有入职时间,算试用期
            empInfoDO.setFormalType(PROBATION.getValue());

            if (turnStraightDate.before(joinDate)) {
                throw new ParamException("转正时间不能早于入职时间");
            }
        }
        // 获取明天时间0点
        Date dateTomorrow = DateUtils.getTomorrow();
        // 转正时间明天之前,已转正
        if (turnStraightDate.before(dateTomorrow)) {
            empInfoDO.setFormalType(FormalTypeEnum.FORMAL.getValue());
            if (isAdd) {
                personalEventService.autoSave(empInfoDO.to(EmpInfoVO.class), tokenUser, PersonalEventEnum.ENTRY.getDesc()
                        , PersonalEventEnum.ENTRY.getValue(), PersonalEventEnum.ENTRY.getDesc());
            }

        } else {
            empInfoDO.setFormalType(PROBATION.getValue());
        }
        empInfoDO.setTurnStraightDate(turnStraightDate);
    }

    /**
     * 批量保存时正式类型/入职时间/试用天数/转正天数的处理
     *
     * @param empInfoDO 员工信息
     */
    private void checkEmpProbationAndFormalBatch(EmpInfoDO empInfoDO) {
        // 如果填了，已填的为准
        if (Objects.nonNull(empInfoDO.getFormalType())) {
            return;
        }
        if (empInfoDO.getJoinDate() == null && empInfoDO.getTurnStraightDate() == null) {
            // 正式类型（0:无状态,1：试用期，2：已转正）
//            empInfoDO.setFormalType(FormalTypeEnum.NOTYPE.getValue());
            return;
        }

        // 入职时间
        Date joinDate = empInfoDO.getJoinDate();
        // 转正时间
        Date turnStraightDate = empInfoDO.getTurnStraightDate();
        // 试用天数
        Integer probationDays = empInfoDO.getProbationDays();

        if (turnStraightDate == null && joinDate != null && probationDays != null) {
            // 没有转正时间,根据入职时间和试用天数计算下转正时间
            turnStraightDate = org.apache.commons.lang3.time.DateUtils.addDays(empInfoDO.getJoinDate(), empInfoDO.getProbationDays());
        }
        empInfoDO.setFormalType(FormalTypeEnum.FORMAL.getValue());
        if (joinDate != null) {
            // 有入职时间,算试用期
            empInfoDO.setFormalType(PROBATION.getValue());
        }
        if (turnStraightDate != null) {
            // 获取明天时间0点
            Date dateTomorrow = DateUtils.getTomorrow();
            // 转正时间明天之前,已转正
            if (turnStraightDate.before(dateTomorrow)) {
                empInfoDO.setFormalType(FormalTypeEnum.FORMAL.getValue());
            } else {
                empInfoDO.setFormalType(PROBATION.getValue());
            }
            empInfoDO.setTurnStraightDate(turnStraightDate);
        }
    }


    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public List<EmpInfoVO> batchSave(List<EmpInfoAddDTO> empInfoAddDTOList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(empInfoAddDTOList)) {
            return null;
        }
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        for (EmpInfoAddDTO empInfoAddDTO : empInfoAddDTOList) {
            EmpInfoVO empInfoVO = save(empInfoAddDTO, tokenUser);
            empInfoVOList.add(empInfoVO);
        }
        return empInfoVOList;
    }

    @Override
    public Page<EmpInfoContractVO> pageEmpListBySigningStatus(EmpListQuery empListQuery, TokenUser tokenUser, Integer signingStatus) {
        // 构造tsgList
        if (StrKit.isNotEmpty(empListQuery.getTag())) {
            empListQuery.setTags(ArrayKit.split(empListQuery.getTag(), ","));
        }
        Page<EmpInfoContractVO> listPage = new Page<>();
        if (empListQuery.getPageNo() > 0) {
            if (signingStatus == 1 || signingStatus == 0 || signingStatus == 2) {
                int startingIndex = (empListQuery.getPageNo() - 1) * empListQuery.getPageSize();
                long currentTime = System.currentTimeMillis();
                long contractEndTime = 0;
                List<EmpInfoContractVO> empInfoContractVOList = empInfoDAO.pageEmpListBySigningStatus(empListQuery, signingStatus, startingIndex, tokenUser.getSiteId());
                if (empInfoContractVOList.size() > 0) {
                    int dataCount = empInfoDAO.empInfoContractCountBySigningStatus(empListQuery, signingStatus, startingIndex, tokenUser.getSiteId());
                    if (signingStatus != 0) {
                        //合同到期天数
                        for (EmpInfoContractVO empInfoContractVO : empInfoContractVOList) {
                            Date contractExpirationDate = empInfoContractVO.getContractExpirationDate();
                            if (contractExpirationDate != null) {
                                //签订日期为空，到期时间也置空防止前端显示
                                if (empInfoContractVO.getStatus() != 3) {
                                    empInfoContractVO.setContractExpirationDate(null);
                                } else {
                                    contractEndTime = empInfoContractVO.getContractExpirationDate().getTime();
                                    empInfoContractVO.setContractExpirationDay((contractEndTime - currentTime) >= 0 ? (contractEndTime - currentTime) / (1000 * 60 * 60 * 24) : -1);
                                }
                            }
                        }
                    }
                    List<EmpInfoContractVO> entities = new ArrayList<>(empInfoContractVOList);
                    listPage.setEntities(entities);
                    listPage.setPageNo(empListQuery.getPageNo());
                    listPage.setPageSize(empListQuery.getPageSize());
                    listPage.setPageCount(dataCount % empListQuery.getPageSize() == 0 ? dataCount / empListQuery.getPageSize() : dataCount / empListQuery.getPageSize() + 1);
                    listPage.setEntityCount(dataCount);
                    listPage.setFirstEntityIndex(startingIndex);
                    listPage.setLastEntityIndex(startingIndex + empListQuery.getPageSize());
                }


            }

        }
        return listPage;

    }

    @Override
    public EmpInfoPasteVO selectEmpInfoByIdCardsAddConUse(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoContractVO> empInfoContractVOList = new ArrayList<>();
        for (String idCard : idCards) {
            if (StrKit.isEmpty(idCard)) {
                continue;
            }
            EmpListQuery empListQuery = new EmpListQuery();
            empListQuery.setIdCard(idCard);
            empListQuery.setCompanyId(companyId);
            empListQuery.setPageSize(10);
            List<EmpInfoContractVO> empInfoContractVOListOne = empInfoDAO.pageEmpListBySigningStatus(empListQuery,
                    2, 0, tokenUser.getSiteId());
            // 判断是否重复
            if (CollectionUtils.isEmpty(empInfoContractVOListOne)) {
                idCardList.add(idCard);
            } else {
                EmpInfoContractVO empInfoContractOne = empInfoContractVOListOne.get(0);
                if (empInfoContractVOList.removeIf(empInfoContractVO ->
                        empInfoContractVO.getEmpId().equals(empInfoContractOne.getEmpId()))) {
                    idCardList.add(idCard);
                }
                empInfoContractVOList.add(empInfoContractOne);
            }
        }
        empInfoPasteVO.setEmpInfoContractVOList(empInfoContractVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int update(EmpInfoUpdateDTO empInfoUpdateDTO, TokenUser tokenUser) {
        //转DO
        EmpInfoDO empInfoDO = empInfoUpdateDTO.to(EmpInfoDO.class);
        // 修改时试用员工的userId 扫码入职userId是system
        EmpInfoVO empInfoVO = selectById(empInfoDO.getId(), tokenUser.getSiteId());
        // 修改前手机号
        String oldPhone = empInfoVO.getPhone();
        // 修改后手机号
        String newPhone = empInfoUpdateDTO.getPhone();
        if (empInfoUpdateDTO.getName() != null) {
            //名字拼音补全
            empInfoDO.setNamePinyin(PinyinKit.nameToPinyin(empInfoUpdateDTO.getName()));
        }
        EmpInfoDO empInfoOld = selectDOById(empInfoUpdateDTO.getId(), tokenUser.getSiteId());
        if (Objects.isNull(empInfoOld)) {
            return 0;
        }

        // 校验标签数量
        checkTag(empInfoUpdateDTO.getTag());

        //小程序端更改个人信息不校验参数
        if (empInfoUpdateDTO.getCheckApp() == null || !empInfoUpdateDTO.getCheckApp()) {

            // 正式类型/入职时间/试用天数/转正天数的处理
            checkEmpProbationAndFormal(false, empInfoDO, tokenUser);
        }

        // 修改预登记人员的渠道id
        if (StrKit.isNotEmpty(empInfoUpdateDTO.getChannelId())) {
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoOld.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                checkInPeopleUpdateDTO.setChannelId(empInfoUpdateDTO.getChannelId());
                checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
            } else {
                // 新建预登记人员（来源为花名册）
                CheckInPeopleAddDTO checkInPeopleAddDTO = new CheckInPeopleAddDTO();
                checkInPeopleAddDTO.setName(empInfoOld.getName());
                checkInPeopleAddDTO.setPhone(empInfoOld.getPhone());
                checkInPeopleAddDTO.setIdcard(empInfoOld.getIdCard());
                checkInPeopleAddDTO.setChannelId(empInfoUpdateDTO.getChannelId());
                checkInPeopleAddDTO.setSource(HrConstants.HUW);
                checkInPeopleAddDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
                checkInPeopleAddDTO.setWorkStatus(CheckInPeopleConstant.WORK_STATUS_RNTRY);
                checkInPeopleService.save(checkInPeopleAddDTO, tokenUser);
            }
        }

        // 修改了手机号
        if (StringUtils.isNotEmpty(newPhone)
                && !newPhone.equals(empInfoOld.getPhone())) {
            // 更新员工合同信息
            contractProviderService.updateUserPhone(empInfoOld.getPhone(), empInfoOld.getUserId(), newPhone, tokenUser);

            // 修改用户的手机号
            userProviderService.updateUserPhone(empInfoOld.getUserId(), oldPhone, newPhone, tokenUser);

            // 修改预登记人员的手机号
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoOld.getPhone(), tokenUser.getSiteId());
            if (Objects.nonNull(checkInPeopleDO)) {
                CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                checkInPeopleUpdateDTO.setPhone(newPhone);
                checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
            }
        }
        // 部门修改
        if (empInfoUpdateDTO.getPreJoinDep() != null) {
            List<EmpDepDO> empDepDOList = empDepService
                    .listAllByEmpId(empInfoUpdateDTO.getCompanyId(), empInfoUpdateDTO.getId(), tokenUser.getSiteId());
            // 删除原有部门
            if (!CollectionUtils.isEmpty(empDepDOList)) {
                empDepService.deleteByIds(tokenUser, empDepDOList.parallelStream().map(BaseDO::getId).toArray(String[]::new));
            }
            if (StringUtils.isNotBlank(empInfoUpdateDTO.getPreJoinDep())) {
                String[] split = empInfoUpdateDTO.getPreJoinDep().split(",");
                List<EmpDepAddDTO> empDepAddDTOList = new ArrayList<>();
                for (String preJoinDep : split) {
                    EmpDepAddDTO empDepAddDTO = new EmpDepAddDTO();
                    empDepAddDTO.setEmpId(empInfoUpdateDTO.getId());
                    empDepAddDTO.setCompanyId(empInfoUpdateDTO.getCompanyId());
                    empDepAddDTO.setDepId(preJoinDep);
                    empDepAddDTOList.add(empDepAddDTO);
                }
                empDepService.batchSave(empDepAddDTOList, tokenUser);
            }
        }
        // 岗位修改
        if (empInfoUpdateDTO.getPreJoinPosition() != null) {
            List<EmpPositionDO> empPositionDOList = empPositionService
                    .listAllByEmpId(empInfoUpdateDTO.getCompanyId(), empInfoUpdateDTO.getId(), tokenUser.getSiteId());
            // 删除原有岗位
            if (!CollectionUtils.isEmpty(empPositionDOList)) {
                empPositionService.deleteByIds(tokenUser, empPositionDOList.parallelStream().map(BaseDO::getId).toArray(String[]::new));
            }
            if (StringUtils.isNotBlank(empInfoUpdateDTO.getPreJoinPosition())) {
                String[] split = empInfoUpdateDTO.getPreJoinPosition().split(",");
                List<EmpPositionAddDTO> empPositionAddDTOList = new ArrayList<>();
                for (String preJoinPosition : split) {
                    EmpPositionAddDTO empPositionAddDTO = new EmpPositionAddDTO();
                    empPositionAddDTO.setEmpId(empInfoUpdateDTO.getId());
                    empPositionAddDTO.setCompanyId(empInfoUpdateDTO.getCompanyId());
                    empPositionAddDTO.setPositionId(preJoinPosition);
                    empPositionAddDTOList.add(empPositionAddDTO);
                }
                empPositionService.batchSave(empPositionAddDTOList, tokenUser);
            }
        }

        //更新身份证号
        String idCard = empInfoDO.getIdCard();
        if (StringUtils.isNotBlank(idCard)) {
            IdcardVO idcardVO = IdcardUtils.analysis(idCard);
            if (idcardVO != null) {
                empInfoDO.setGender(idcardVO.getGender());
                empInfoDO.setBirthday(idcardVO.getBiethday());
            }
        }

        try {
            //退休日期、退休年龄、出生日期发生变化发送通知
            List<EmpInfoDO> empInfoDOS = new ArrayList<>();
            empInfoDOS.add(empInfoDO);
            sendRetirement(empInfoDOS);
        } catch (Exception e) {
            log.info("人员修改退休日期发送通知失败");
        }
        //根据主键更新，只更新非null值
        return updateByIdSelective(empInfoDO, tokenUser.getSiteId(), empInfoVO.getUserId());
    }


    /**
     * 修改退休信息发送退休通知
     * <p>
     * 有退休日期，原来有没有，原来没有，发送，原来有，对比时间是否一样，一样不发不一样发
     * 没有退休日期
     * 有退休年龄，没有出生日期，看原来有没有出生日期，没有就不发，有的话看原来年龄有没有，没有就发，有的话再看是否一样，一样不发，不一样发
     * 有退休年龄，有出生日期，看原来有没有出生日期和退休年龄
     * 原来没有出生日期和退休年龄，发送
     * 原来没有出生日期有退休年龄，退休年龄是否一样，不一样不发送，一样的话发送
     * 原来有出生日期和退休年龄，发送,看退休年龄是否一样，不一样不发送，一样的话再看出生年月，出生日期一样不发送，不一样发送
     * 没有退休年龄，没有出生日期，不发送
     *
     * @param empInfoDOList 员工信息list
     */
    private void sendRetirement(List<EmpInfoDO> empInfoDOList) {
        try {
            NoticeRuleSettingVO ruleSettingVO = noticeProviderService.selectByTypeCodeAndCompany(HrConstants.HR_SUBJECT_TYPE,
                    NoticeConstants.RETIRE, empInfoDOList.get(0).getCompanyId());
            if (ruleSettingVO == null || ruleSettingVO.getId() == null || !ruleSettingVO.getEnableStatus()) {
                return;
            }
            List<EmpInfoDO> empInfoDOS = new ArrayList<>();
            for (EmpInfoDO empInfoDO : empInfoDOList) {
                EmpInfoDO empInfoDO1 = selectById(empInfoDO.getId());
                if (empInfoDO.getRetirementDate() != null) {
                    if (empInfoDO1.getRetirementDate() == null) {
                        empInfoDO1.setRetirementDate(empInfoDO.getRetirementDate());
                        empInfoDOS.add(empInfoDO1);
                    } else if (empInfoDO1.getRetirementDate() != null && !DateUtil.isSameTime(empInfoDO1.getRetirementDate(), empInfoDO.getRetirementDate())) {
                        empInfoDO1.setRetirementDate(empInfoDO.getRetirementDate());
                        empInfoDOS.add(empInfoDO1);
                    }
                } else {
                    if (empInfoDO.getRetirementAge() != null && empInfoDO.getBirthday() == null) {
                        if (empInfoDO1.getBirthday() != null) {
                            if (empInfoDO1.getRetirementAge() == null) {
                                empInfoDO1.setRetirementDate(DateUtil.offset(DateUtil.parse(empInfoDO1.getBirthday()), DateField.YEAR, empInfoDO.getRetirementAge()));
                                empInfoDOS.add(empInfoDO1);
                            } else if (empInfoDO1.getRetirementAge().equals(empInfoDO.getRetirementAge())) {
                                empInfoDO1.setRetirementDate(DateUtil.offset(DateUtil.parse(empInfoDO1.getBirthday()), DateField.YEAR, empInfoDO.getRetirementAge()));
                                empInfoDOS.add(empInfoDO1);
                            }
                        }
                    } else if (empInfoDO.getRetirementAge() != null && empInfoDO.getBirthday() != null) {
                        if (empInfoDO1.getRetirementAge() == null && empInfoDO1.getBirthday() == null) {
                            empInfoDO1.setRetirementDate(DateUtil.offset(DateUtil.parse(empInfoDO1.getBirthday()), DateField.YEAR, empInfoDO.getRetirementAge()));
                            empInfoDOS.add(empInfoDO1);
                        } else if (empInfoDO1.getRetirementAge() != null && empInfoDO1.getBirthday() == null) {
                            if (empInfoDO1.getRetirementAge().equals(empInfoDO.getRetirementAge())) {
                                empInfoDO1.setRetirementDate(DateUtil.offset(DateUtil.parse(empInfoDO.getBirthday()), DateField.YEAR, empInfoDO.getRetirementAge()));
                                empInfoDOS.add(empInfoDO1);
                            }
                        } else if (empInfoDO1.getRetirementAge() != null && empInfoDO1.getBirthday() != null) {
                            if (empInfoDO1.getRetirementAge().equals(empInfoDO.getRetirementAge())) {
                                if (!empInfoDO1.getBirthday().equals(empInfoDO.getBirthday())) {
                                    empInfoDO1.setRetirementDate(DateUtil.offset(DateUtil.parse(empInfoDO.getBirthday()), DateField.YEAR, empInfoDO.getRetirementAge()));
                                    empInfoDOS.add(empInfoDO1);
                                }
                            }
                        }
                    }
                }
            }
            if (CollectionUtils.isEmpty(empInfoDOS)) {
                return;
            }
            sendNoticeTask.addTask(empInfoDOS, NoticeConstants.RETIRE, "员工退休发送通知", ReceiveDateTypeEnum.FIXED.getDesc(), new Date());
        } catch (Exception e) {
            log.info("人员修改退休日期发送通知失败");
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int deleteByIds(TokenUser tokenUser, String... empInfoIds) {
        // 删除员工同时删除员工变动记录
        List<String> empIds = Arrays.asList(empInfoIds);
        Integer integer = empChangesService.deleteByEmpIds(empIds, tokenUser);
        log.info("删除员工时同步删除变动记录{}条", integer);
        // ID1001891：删除员工未归档的月工资
        salaryProviderService.deleteEmployeeSalaryNotArchiveByEmpIds(empIds, tokenUser);
        for (String empInfoId : empInfoIds) {
//            Boolean haveEmpSocInfo = empSocInfoService.findEmpHaveInfo(empInfoId, tokenUser);
//            ParamException.isTrue(!haveEmpSocInfo, "该员工已有参保记录，无法删除");
            EmpInfoDO empInfoDO = selectDOById(empInfoId, tokenUser.getSiteId());

            //删除预登记记录
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
            if (checkInPeopleDO != null) {
                OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
                operationEmpRecordQuery.setCheckInId(checkInPeopleDO.getId());
                List<OperationEmpRecordListVO> select = operationEmpRecordService.select(operationEmpRecordQuery, tokenUser.getSiteId());
                for (OperationEmpRecordListVO operationEmpRecordListVO : select) {
                    operationEmpRecordService.deleteByIds(tokenUser, operationEmpRecordListVO.getId());
                }
            }

            // 根据手机号查询预登记人员，如果有则删除预登记人员信息
            checkInPeopleService.deleteByPhone(tokenUser, empInfoDO.getPhone());
            /*CompanyDO companyDO = companyService.selectDOById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
            HrLogKit.logForSave("由管理员" + tokenUser.getUserName() + "删除员工,员工姓名:" + empInfoDO.getName(),
                    "empInfo", empInfoDO.getId(), companyDO.getId(), tokenUser);*/

            //删除员工记录
            OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
            operationEmpRecordQuery.setEmpId(empInfoId);
            List<OperationEmpRecordListVO> select = operationEmpRecordService.select(operationEmpRecordQuery, tokenUser.getSiteId());
            for (OperationEmpRecordListVO operationEmpRecordListVO : select) {
                operationEmpRecordService.deleteByIds(tokenUser, operationEmpRecordListVO.getId());
            }
            empSocRelatedService.deleteByEmpId(empInfoId, tokenUser);
        }


        return logicalDeleteByIds(tokenUser.getSiteId(), tokenUser.getUserId(), (Object[]) empInfoIds);
    }


    @Override
    public EmpInfoVO selectById(String empInfoId, String siteId) {
        EmpInfoDO empInfoDO = selectDOById(empInfoId, siteId);
        if (empInfoDO == null) {
            return null;
        }
        //        // 部门
//        String preJoinDep = empInfoDO.getPreJoinDep();
//        if (preJoinDep != null) {
//            DepInfoVO depInfoVO = depInfoService.selectById(empInfoDO.getPreJoinDep(), siteId);
//            if (depInfoVO != null) {
//                empInfoVO.setPreJoinDep(depInfoVO.getName());
//            }
//        }
//        // 岗位
//        String preJoinPosition = empInfoDO.getPreJoinPosition();
//        if (preJoinPosition != null) {
//            PositionInfoVO positionInfoVO = positionInfoService.selectById(empInfoDO.getPreJoinPosition(), siteId);
//            if (positionInfoVO != null) {
//                empInfoVO.setPreJoinPosition(positionInfoVO.getName());
//            }
//        }
        EmpInfoVO empInfoVO = empInfoDO.to(EmpInfoVO.class);
        String idCard = empInfoDO.getIdCard();
        if (StringUtils.isNotBlank(idCard)) {
            IdcardVO idcardVO = IdcardUtils.analysis(idCard);
            if (idcardVO != null) {
                empInfoVO.setEmpAge(idcardVO.getAge());
            }
        }
        if (StrKit.isNotEmpty(empInfoVO.getChannelId())) {
            ChannelVO channelVO = channelService.selectById(empInfoVO.getChannelId(), siteId);
            empInfoVO.setChannelVO(channelVO);
        }
        try {
            OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
            operationEmpRecordQuery.setEmpId(empInfoVO.getId());
            List<OperationEmpRecordListVO> select = operationEmpRecordService.select(operationEmpRecordQuery, siteId);
            if (!CollectionUtils.isEmpty(select)) {
                List<String> checkInId = select.stream()
                        .map(OperationEmpRecordListVO::getCheckInId)
                        .filter(id -> !StringUtils.isEmpty(id)).collect(Collectors.toList());
                OperationEmpRecordListVO operationEmpRecordListVO1 = null;
                if (CollectionUtils.isEmpty(checkInId)) {
                    operationEmpRecordListVO1 = select.get(0);
                } else {
                    OperationEmpRecordQuery operationEmpRecordQuery1 = new OperationEmpRecordQuery();
                    operationEmpRecordQuery1.setCheckInId(checkInId.get(0));
                    List<OperationEmpRecordListVO> select1 = operationEmpRecordService.select(operationEmpRecordQuery1, siteId);
                    for (OperationEmpRecordListVO operationEmpRecordListVO : select1) {
                        if (operationEmpRecordListVO.getSourceTypeInfo().contains("转")) {
                            operationEmpRecordListVO1 = operationEmpRecordListVO;
                            break;
                        }
                    }
                }
                if (operationEmpRecordListVO1 != null) {
                    empInfoVO.setSourceType(operationEmpRecordListVO1.getSourceType());
                    UserDO userDO = userProviderService.selectUserById(operationEmpRecordListVO1.getInputUserId());
                    if (userDO != null) {
                        empInfoVO.setInputName(userDO.getName());
                    }
                }
            }
        } catch (Exception e) {
            log.error("InputUser为空");
        }
        return empInfoVO;
    }

    @Override
    public EmpInfoDO selectById(String empInfoId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("id", empInfoId);
        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public EmpInfoDO selectByIdNotValid(String empInfoId) {
        Example example = new Example(EmpInfoDO.class);
        example.and().andEqualTo("id", empInfoId);
        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public List<EmpInfoListVO> select(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        return getVoListByDoList(selectDO(empInfoQuery, tokenUser));
    }

    /**
     * 根据doList获取voList
     *
     * @param doList do
     * @return vo
     */
    private List<EmpInfoListVO> getVoListByDoList(List<EmpInfoDO> doList) {
        if (CollectionUtils.isEmpty(doList)) {
            return new ArrayList<>();
        }
        return doList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class))
                .collect(Collectors.toList());
    }

    @Override
    public int selectCount(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        return empInfoDAO.selectCountByExample(example);
    }

    @Override
    public Page<EmpInfoListVO> selectPage(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        Page<EmpInfoDO> page = empInfoDAO.selectPageByExample(example,
                empInfoQuery.getPageNo(),
                empInfoQuery.getPageSize());

        return page.to(EmpInfoListVO.class);
    }

    @Override
    public EmpInfoDO selectDOById(String empInfoId, String siteId) {
        return listById(empInfoId, siteId);
    }

    @Override
    public EmpInfoDO selectDOByIdIgnoreValid(String empInfoId) {
        Example example = new Example(EmpInfoDO.class);
        example.and().andEqualTo("id", empInfoId);
        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectDoByIdsIgnoreValid(List<String> empInfoIds) {
        if (CollectionUtils.isEmpty(empInfoIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and().andIn("id", empInfoIds);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectDoByIds(List<String> empInfoIds) {
        if (CollectionUtils.isEmpty(empInfoIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("id", empInfoIds);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectOnJobDoByIds(List<String> empInfoIds) {
        if (CollectionUtils.isEmpty(empInfoIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("id", empInfoIds);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectOnJobDoByMonthAndCompanyId(String companyId
            , int yearly, int monthly, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        Date date;
        if (monthly < 10) {
            date = DateKit8.parseDate(yearly + "-0" + monthly + "-01");
        } else {
            date = DateKit8.parseDate(yearly + "-" + monthly + "-01");
        }
        // 入职时间小于当月最后一秒
        example.and().andLessThanOrEqualTo("joinDate", DateKit8.getEndTime(DateKit8.getLastDayOfMonth(date)));
        // 离职时间晚于当月第一秒
        example.and()
                .orIsNull("leaveDate")
                .orGreaterThanOrEqualTo("leaveDate", DateKit8.getFirstDayOfMonth(date));
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectDO(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        return empInfoDAO.selectByExample(example);
    }


    @Override
    public String selectExportList(EmpInfoExportQuery empInfoExportQuery, TokenUser tokenUser) {
        long l1 = System.currentTimeMillis();
        log.info("======花名册导出开始======");
        final String BANK_PLACE = "bankPlace";
        final String BIRTHDAY = "birthday";
        //查询所有的模板字段
        List<HeaderFieldsTemplateListVO> allTemplateField = adminProviderService.getAllTemplateField(EMP_INFO_BY_COMPANY);
        List<String> allTemplateFieldString = new ArrayList<>();
        if (!CollectionUtils.isEmpty(allTemplateField)) {
            allTemplateFieldString = allTemplateField.parallelStream().map(HeaderFieldsTemplateListVO::getCode).collect(Collectors.toList());
        }
        List<EmpInfoExportColumn> exportColumns = empInfoExportQuery.getExportColumns();
        Map<String, String> headMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(exportColumns)) {
            headMap = exportColumns.parallelStream().collect(Collectors.toMap(EmpInfoExportColumn::getDataIndex, EmpInfoExportColumn::getTitle));
        }
        // 定义要导出的所有表头集合
        // 表头为中文名，所以需要再定义一个英文名的集合，准备反射获取属性
        List<List<String>> headList = new ArrayList<>();
        // 表头英文名集合
        List<String> headPropertyList = new ArrayList<>();
        for (EmpInfoExportColumn empInfoExportColumn : empInfoExportQuery.getExportColumns()) {
            // 定义每一个表头
            List<String> oneHead = new ArrayList<>();
            oneHead.add(empInfoExportColumn.getTitle());
            headList.add(oneHead);
            headPropertyList.add(empInfoExportColumn.getDataIndex());
        }
        EmpInfoQuery empInfoQuery = new EmpInfoQuery();
        empInfoQuery.setCompanyId(empInfoExportQuery.getCompanyId());
        empInfoQuery.setIdList(empInfoExportQuery.getIdList());
        empInfoQuery.setStatus(empInfoExportQuery.getStatus());

        empInfoQuery.setNameOrPhone(empInfoExportQuery.getNameOrPhoneOrIdCard());
        empInfoQuery.setFormalType(empInfoExportQuery.getFormalType());
        empInfoQuery.setGender(empInfoExportQuery.getGender());
        empInfoQuery.setHighestEducation(empInfoExportQuery.getHighestEducation());
        empInfoQuery.setIsImprove(empInfoExportQuery.getIsImprove());
        empInfoQuery.setVerified(empInfoExportQuery.getVerified());
        empInfoQuery.setPostType(empInfoExportQuery.getPostType());
        empInfoQuery.setPoliticalStatus(empInfoExportQuery.getPoliticalStatus());
        empInfoQuery.setMaritalStatus(empInfoExportQuery.getMaritalStatus());
        empInfoQuery.setContractsStatus(empInfoExportQuery.getContractsStatus());
        empInfoQuery.setTag(empInfoExportQuery.getTag());
        empInfoQuery.setChannelId(empInfoExportQuery.getChannelId());
        empInfoQuery.setJoinDateStart(empInfoExportQuery.getJoinDateStart());
        empInfoQuery.setJoinDateEnd(empInfoExportQuery.getJoinDateEnd());
        //查询到数据
        List<EmpInfoListVO> EmpInfoListVOList = listOnJobEmpList(empInfoQuery, tokenUser);
        long l2 = System.currentTimeMillis();
        log.info("======花名册导出：获取{}条在职员工列表,耗时：{}ms", EmpInfoListVOList.size(), (l2 - l1));
        // 定义所有的数据集合
        List<List<String>> dataList = new ArrayList<>();
        // 公司下自定义字段
        List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList
                = companyAdditionalFieldsService.selectByCompanyId(empInfoExportQuery.getCompanyId(), tokenUser.getSiteId());
        // 只取基本信息 和联系信息的自定义字段 员工状态 在职信息 档案信息 退休信息
        companyAdditionalFieldsListVOList = companyAdditionalFieldsListVOList.parallelStream()
                .filter(companyAdditionalFieldsListVO -> (
                        "basic".equals(companyAdditionalFieldsListVO.getModuleCode())
                                || "contact".equals(companyAdditionalFieldsListVO.getModuleCode())
                                || "empState".equals(companyAdditionalFieldsListVO.getModuleCode())
                                || "onJob".equals(companyAdditionalFieldsListVO.getModuleCode())
                                || "file".equals(companyAdditionalFieldsListVO.getModuleCode())
                                || "retire".equals(companyAdditionalFieldsListVO.getModuleCode()))
                ).collect(Collectors.toList());
        // 自定义字段名称-Id
        Map<String, Long> fieldNameIdMap = companyAdditionalFieldsListVOList.stream().collect(Collectors
                .toMap(CompanyAdditionalFieldsListVO::getFieldName, CompanyAdditionalFieldsListVO::getId, (k1, k2) -> k1));
        // id-自定义字段Map
        Map<Long, CompanyAdditionalFieldsListVO> idFieldMap = companyAdditionalFieldsListVOList.stream()
                .collect(Collectors.toMap(CompanyAdditionalFieldsListVO::getId, v -> v));
        List<String> valuesList = fieldNameIdMap.values().stream().map(p -> p + "").collect(Collectors.toList());
        long l3 = System.currentTimeMillis();
        log.info("======花名册导出：获取员工自定义数据,耗时：{}ms", (l3 - l2));
        // 员工id
        List<String> empIdList = EmpInfoListVOList.parallelStream()
                .map(EmpInfoListVO::getId).collect(Collectors.toList());
        // 每个员工的自定义字段
        Map<String, List<EmpAdditionalFieldsDO>> empIdFieldsMap = empAdditionalFieldsService
                .selectByFiledIdsAndEmpIds(new ArrayList<>(fieldNameIdMap.values()), empIdList);

        //工作性质
        List<DictItemDO> postTypeList = adminProviderService.selectAllDictItem(null, POST_TYPE, tokenUser);
        Map<String, String> postTypeMap = postTypeList.stream().collect(Collectors.toMap(DictItemDO::getDictItemValue, DictItemDO::getDictItemKey, (key1, key2) -> key2));

        // 循环查询到的数据,准备拼装数据
        for (EmpInfoListVO empInfoListVO : EmpInfoListVOList) {
            // 定义每一条数据
            List<String> oneData = new ArrayList<>();
            List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empIdFieldsMap.get(empInfoListVO.getId());
            // 自定义字段id-内容
            Map<Long, String> fieldIdContentMap = new HashMap<>();
            if (!CollectionUtils.isEmpty(empAdditionalFieldsDOList)) {
                // 自定义字段-值
                fieldIdContentMap = empAdditionalFieldsDOList.stream().peek(empAdditionalFieldsDO -> {
                    if (empAdditionalFieldsDO.getContent() == null) {
                        empAdditionalFieldsDO.setContent("");
                    } else {
                        // 如果自定义字段是地区类型，需要处理一下
                        CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO = idFieldMap.get(empAdditionalFieldsDO.getFieldId());
                        if (Objects.equals(FIELD_TYPE_AREA, companyAdditionalFieldsListVO.getFieldType())) {
                            String areaName = adminProviderService.getAreaNameByIds(empAdditionalFieldsDO.getContent());
                            empAdditionalFieldsDO.setContent(areaName);
                        }
                    }
                }).collect(Collectors.toMap(EmpAdditionalFieldsDO::getFieldId, EmpAdditionalFieldsDO::getContent, (k1, k2) -> k1));
            }
            //循环表头,往每一条数据中，拼装数据
            for (String head : headPropertyList) {
                try {
                    Field field = empInfoListVO.getClass().getDeclaredField(head);
                    field.setAccessible(true);
                    if (field.get(empInfoListVO) != null) {
                        //如果这个属性是Date类型需要做特殊处理
                        if (field.getGenericType().toString().equals(DATE_STR)) {
                            Date date = (Date) field.get(empInfoListVO);
                            oneData.add(DateKit8.format2Date(date));
                        } else {
                            if (BANK_PLACE.equals(head)) {
                                String bankPlaceIds = empInfoListVO.getBankPlace();
                                if (StrKit.isEmpty(bankPlaceIds)) {
                                    oneData.add("");
                                    continue;
                                }
                                String bankPlaceName = adminProviderService.getAreaNameByIds(bankPlaceIds);
                                oneData.add(bankPlaceName);
                            } else if (BIRTHDAY.equals(head)) {
                                String value = EmpInfoFieldToString.fieldToString(field, empInfoListVO, postTypeMap);
                                oneData.add(DateKit8.format2Date(DateKit8.parseDate(value)));
                            } else {
                                String value = EmpInfoFieldToString.fieldToString(field, empInfoListVO, postTypeMap);
                                oneData.add(value);
                            }
                        }
                    } else {
                        oneData.add("");
                    }

                } catch (NoSuchFieldException e) {
                    //是否自定义字段
                    if (!valuesList.contains(head)) {
                        //是否是模板字段
                        if (!CollectionUtils.isEmpty(allTemplateFieldString) && allTemplateFieldString.contains(head) && headMap.containsKey(head)) {
                            String value = headMap.get(head);
                            headList.removeIf(next -> next.contains(value));
                        } else {
                            Long field = fieldNameIdMap.get(head);
                            if (field == null) {
                                throw new ParamException("表头传入错误");
                            }
                            String fieldContent = fieldIdContentMap.get(field);
                            oneData.add(fieldContent);
                        }
                    } else {
                        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOS = empIdFieldsMap.get(empInfoListVO.getId());
                        if (CollectionUtils.isEmpty(empAdditionalFieldsDOS)) {
                            oneData.add("");
                        } else {
                            Map<String, String> stringStringMap = empAdditionalFieldsDOS.parallelStream().collect(Collectors.toMap(p -> p.getFieldId() + "", p -> StringUtils.isEmpty(p.getContent()) ? "" : p.getContent()));
                            oneData.add(stringStringMap.getOrDefault(head, ""));
                        }
                    }
                } catch (IllegalAccessException e) {
                    throw new ParamException("无法访问属性");
                }
            }
            dataList.add(oneData);
        }
        long l4 = System.currentTimeMillis();
        log.info("======花名册导出：处理数据,耗时：{}ms", (l4 - l3));
        String excelUrl = ExcelKit.exportExcelDynamic("emptyEmpPage", "员工列表", dataList, headList);
        long l5 = System.currentTimeMillis();
        log.info("======花名册导出：写入{}条excel,耗时：{}ms", dataList.size(), (l5 - l4));
        return excelUrl;
    }

    @Override
    public List<ParseResultVO<EmpInfoImportDTO>> parseImportFile(File file, Boolean success, TokenUser tokenUser) {
        EmpInfoImportListener empInfoImportListener = new EmpInfoImportListener();
        empInfoImportListener.setTokenUser(tokenUser);
        empInfoImportListener.setParseOnly(true);
        // 读取excel 只解析不入库
        EasyExcel.read(file, EmpInfoImportDTO.class, empInfoImportListener).sheet().doRead();
        if (success == null) {
            return empInfoImportListener.getParseResultList();
        } else {
            return empInfoImportListener.getParseResultList()
                    .stream()
                    .filter(parseResult -> success.equals(parseResult.getSuccess()))
                    .collect(Collectors.toList());
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO importFile(File file, TokenUser tokenUser, Boolean force, String companyId) {
        EmpInfoImportListener empInfoImportListener = new EmpInfoImportListener();
        empInfoImportListener.setTokenUser(tokenUser);
        empInfoImportListener.setForce(force);
        empInfoImportListener.setCompanyId(companyId);
        // 读取excel 并且入库
        EasyExcel.read(file, EmpInfoImportDTO.class, empInfoImportListener).sheet(HrConstants.EMP_IMPORT_SHEET_NAME).doRead();
        return empInfoImportListener.getEmpImportExcelVO();
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO importFileZhiXinRen(File file, TokenUser tokenUser, Boolean force, String companyId) {
        //  1.校验redis 是否存在正在导入操作
        String lockKey = CacheKeyKit.getEmpInfoImportKey(companyId);
        RLock lock = redissonClient.getLock(lockKey);
        if (lock.isLocked()) {
            log.warn("花名册导入重复点击");
            throw new ParamException("请等待花名册导入完成");
        }
        EmpInfoImportZhiXinRenListener empInfoImportZhiXinRenListener = new EmpInfoImportZhiXinRenListener();
        empInfoImportZhiXinRenListener.setTokenUser(tokenUser);
        empInfoImportZhiXinRenListener.setForce(force);
        empInfoImportZhiXinRenListener.setCompanyId(companyId);
        empInfoImportZhiXinRenListener.setAdd(true);
        // 读取excel 并且入库
        ExcelReader excelReader = EasyExcel.read(file, empInfoImportZhiXinRenListener).build();
        //所有列表
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
        boolean flag = false;
        for (ReadSheet readSheet : sheets) {
            // 一个个开始读取里面的数据
            if (readSheet.getSheetName().equals(HrConstants.EMP_IMPORT_SHEET_NAME)) {
                excelReader.read(readSheet);
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new ParamException("模板中找不到指定的sheet页【" + HrConstants.EMP_IMPORT_SHEET_NAME + "】");
        }
        excelReader.finish();
        return empInfoImportZhiXinRenListener.getEmpImportExcelVO();
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO importZhiXinRenForSite(File file, TokenUser tokenUser, Boolean force) {
        //  1.校验redis 是否存在正在导入操作
        String lockKey = CacheKeyKit.getEmpInfoImportKey(tokenUser.getSiteId());
        RLock lock = redissonClient.getLock(lockKey);
        if (lock.isLocked()) {
            log.warn("花名册导入重复点击");
            throw new ParamException("请等待花名册导入完成");
        }
        EmpInfoImportZhiXinRenBySiteListener empInfoImportZhiXinRenBySiteListener = new EmpInfoImportZhiXinRenBySiteListener();
        empInfoImportZhiXinRenBySiteListener.setTokenUser(tokenUser);
        empInfoImportZhiXinRenBySiteListener.setForce(force);
        empInfoImportZhiXinRenBySiteListener.setSiteId(tokenUser.getSiteId());
        empInfoImportZhiXinRenBySiteListener.setAdd(true);
        // 读取excel 并且入库
        ExcelReader excelReader = EasyExcel.read(file, empInfoImportZhiXinRenBySiteListener).build();
        //所有列表
        List<ReadSheet> sheets = excelReader.excelExecutor().sheetList();
        boolean flag = false;
        for (ReadSheet readSheet : sheets) {
            // 一个个开始读取里面的数据
            if (readSheet.getSheetName().equals(HrConstants.EMP_IMPORT_SHEET_NAME)) {
                excelReader.read(readSheet);
                flag = true;
                break;
            }
        }
        if (!flag) {
            throw new ParamException("模板中找不到指定的sheet页【" + HrConstants.EMP_IMPORT_SHEET_NAME + "】");
        }
        excelReader.finish();
        return empInfoImportZhiXinRenBySiteListener.getEmpImportExcelVO();
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO importFileZhiXinRenForUpdate(File file, TokenUser tokenUser, Boolean force, String companyId) {
        //  1.校验redis 是否存在正在导入操作
        String lockKey = CacheKeyKit.getEmpInfoImportKey(companyId);
        RLock lock = redissonClient.getLock(lockKey);
        if (lock.isLocked()) {
            log.warn("花名册导入重复点击");
            throw new ParamException("请等待花名册导入完成");
        }
        EmpInfoImportZhiXinRenListener empInfoImportZhiXinRenListener = new EmpInfoImportZhiXinRenListener();
        empInfoImportZhiXinRenListener.setTokenUser(tokenUser);
        empInfoImportZhiXinRenListener.setForce(force);
        empInfoImportZhiXinRenListener.setCompanyId(companyId);
        empInfoImportZhiXinRenListener.setAdd(false);
        // 读取excel 并且入库
        EasyExcel.read(file, empInfoImportZhiXinRenListener).sheet(HrConstants.EMP_IMPORT_SHEET_NAME).doRead();
        return empInfoImportZhiXinRenListener.getEmpImportExcelVO();
    }

    @Override
    public String exportByEmpIds(List<String> empIds, String companyId, TokenUser tokenUser) {
        SiteVO site = adminProviderService.selectSiteById(tokenUser.getSiteId(), tokenUser);
        List<EmpInfoDO> empInfoDOList = selectDoByIds(empIds);
        ParamException.notEmpty(empInfoDOList, "没有可以导出的员工");
        // 表头容器定义
        List<List<String>> headList = new ArrayList<>();
        // 所有的数据容器定义
        List<List<String>> dataList = new ArrayList<>();
        // 公司下自定义字段
        List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList
                = companyAdditionalFieldsService.selectByCompanyId(companyId, tokenUser.getSiteId());
        // 取基本信息,联系信息,员工状态,在职信息,档案信息,退休信息  的自定义字段
        List<String> codeList = Arrays.asList("basic", "contact", "empState", "onJob", "file", "retire");
        companyAdditionalFieldsListVOList = companyAdditionalFieldsListVOList.parallelStream()
                .filter(field -> codeList.contains(field.getModuleCode())).collect(Collectors.toList());
        // 自定义字段Id-名称
        LinkedHashMap<Long, String> fieldIdNameMap = companyAdditionalFieldsListVOList.stream().collect(Collectors
                .toMap(CompanyAdditionalFieldsListVO::getId, CompanyAdditionalFieldsListVO::getFieldName, (k1, k2) -> k1, LinkedHashMap::new));
        // 自定义字段id-内容
        Map<Long, CompanyAdditionalFieldsListVO> idFieldMap = companyAdditionalFieldsListVOList.stream().collect(Collectors
                .toMap(CompanyAdditionalFieldsListVO::getId, v -> v));

        //工作性质
        List<DictItemDO> postTypeList = adminProviderService.selectAllDictItem(null, POST_TYPE, tokenUser);
        Map<String, String> postTypeMap = postTypeList.stream().collect(Collectors.toMap(DictItemDO::getDictItemValue, DictItemDO::getDictItemKey, (key1, key2) -> key2));
        String postTypeStr = "工作性质：劳务派遣,外包,社保代缴,薪资代发,其他";
        List<String> postTypeKeyList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(postTypeList)) {
            String postTypeStrNew = "工作性质：";
            for (DictItemDO dictItemDO : postTypeList) {
                postTypeStrNew = postTypeStrNew + dictItemDO.getDictItemKey() + ",";
                postTypeKeyList.add(dictItemDO.getDictItemKey());
            }
            postTypeStrNew = postTypeStrNew.substring(0, postTypeStrNew.length()-1);
            postTypeStr = postTypeStrNew;
        }

        // 导出表头
        List<String> header = new ArrayList<>();
        header.add("姓名");
        header.add("身份证号");
        if (!(JIA_FANG_SY.equals(site.getSiteType()) || JIA_FANG_QY.equals(site.getSiteType()))) {
            header.add("工作性质");
        }
        header.add("入职日期");
        header.add("备注");
        header.add("标签");
        header.add("婚姻状况");
        header.add("生育状况");
        header.add("民族");
        header.add("政治面貌");
        header.add("户口类型");
        header.add("户籍地址");
        header.add("血型");
        header.add("个人邮箱");
        header.add("现居住地");
        header.add("渠道来源");
        header.add("员工状态");
        header.add("试用期");
        header.add("转正日期");
        header.add("工号");
        header.add("部门");
        header.add("岗位");
        header.add("工作地点");
        header.add("入职城市");
        header.add("签约主体");
        header.add("档案编号");
        header.add("档案备注");
        header.add("是否已退休");
        header.add("退休日期");
        header.add("退休备注");
        header.add("工资卡卡号");
        header.add("银行名称");
        header.add("工资卡开户城市");
        header.add("工资卡开户支行");
        header.add("是否首次缴纳社保");
        header.add("个人社保卡号");
        header.add("是否首次缴纳公积金");
        header.add("个人公积金账号");
        header.add("学历");
        for (Long fieldId : fieldIdNameMap.keySet()) {
            header.add(fieldIdNameMap.get(fieldId));
        }
        // 导出数据
        for (String head : header) {
            List<String> oneHead = new ArrayList<>();
            oneHead.add(head);
            headList.add(oneHead);
        }

        for (EmpInfoDO empInfoDO : empInfoDOList) {
            List<String> oneDate = new ArrayList<>();
            oneDate.add(empInfoDO.getName());
            oneDate.add(empInfoDO.getIdCard());
            if (!(JIA_FANG_SY.equals(site.getSiteType()) || JIA_FANG_QY.equals(site.getSiteType()))) {
                if (empInfoDO.getPostType() != null) {
//                    oneDate.add(PostType.find(empInfoDO.getPostType()).getDesc());
                    //TODO
                    oneDate.add(postTypeMap.get(String.valueOf(empInfoDO.getPostType())));
                } else {
                    oneDate.add("");
                }
            }
            if (empInfoDO.getJoinDate() != null) {
                oneDate.add(DateKit8.format(empInfoDO.getJoinDate(), "yyyy-MM-dd"));
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getRemark());
            oneDate.add(empInfoDO.getTag());
            if (empInfoDO.getMaritalStatus() != null) {
                oneDate.add(EmpMaritalStatus.find(empInfoDO.getMaritalStatus()).getDesc());
            } else {
                oneDate.add("");
            }
            if (empInfoDO.getBirthStatus() != null) {
                oneDate.add(EmpBirthStatus.find(empInfoDO.getBirthStatus()).getDesc());
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getNation());
            if (empInfoDO.getPoliticalStatus() != null) {
                oneDate.add(EmpPoliticalStatus.find(empInfoDO.getPoliticalStatus()).getDesc());
            } else {
                oneDate.add("");
            }
            if (empInfoDO.getRegType() != null) {
                oneDate.add(RegTypeEnum.find(empInfoDO.getRegType()).getDesc());
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getNativeLocation());
            if (empInfoDO.getBloodGroup() != null) {
                oneDate.add(BloodGroupEnum.find(empInfoDO.getBloodGroup()).getDesc());
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getEmail());
            oneDate.add(empInfoDO.getCurrentLocation());
            if (empInfoDO.getChannelId() != null) {
                ChannelVO channelVO = channelService.selectById(empInfoDO.getChannelId(), tokenUser.getSiteId());
                if (channelVO != null) {
                    oneDate.add(channelVO.getName());
                } else {
                    oneDate.add("");
                }
            } else {
                oneDate.add("");
            }
            if (empInfoDO.getFormalType() != null) {
                oneDate.add(FormalTypeEnum.find(empInfoDO.getFormalType()).getDesc());
            } else {
                oneDate.add("");
            }
            // 试用期为空 导出为0
            if (empInfoDO.getProbationDays() != null) {
                oneDate.add(empInfoDO.getProbationDays() + "");
            } else {
                oneDate.add("0");
            }

            if (empInfoDO.getTurnStraightDate() != null) {
                oneDate.add(DateKit8.format(empInfoDO.getTurnStraightDate(), "yyyy-MM-dd"));
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getNumber());
            // 部门
            if (StringUtils.isNotBlank(empInfoDO.getPreJoinDep())) {
                String[] split = empInfoDO.getPreJoinDep().split(",");
                String depName = "";
                for (String depId : split) {
                    DepInfoVO depInfoVO = depInfoService.selectById(depId, tokenUser.getSiteId());
                    if (depInfoVO == null) {
                        continue;
                    }
                    String parentId = depInfoVO.getParentId();
                    depName = depInfoVO.getName();
                    // 导出部门与新增保持一致
                    for (Integer level = depInfoVO.getLevel(); level > 3; level--) {
                        // 父级部门
                        DepInfoVO parentDepInfoVO = depInfoService.selectById(parentId, tokenUser.getSiteId());
                        if (parentDepInfoVO == null) {
                            depName = "";
                            break;
                        }
                        depName = parentDepInfoVO.getName() + "/" + depName;
                        parentId = parentDepInfoVO.getParentId();
                    }
                    break;
                }
                oneDate.add(depName);
            } else {
                oneDate.add("");
            }
            // 岗位
            if (StringUtils.isNotBlank(empInfoDO.getPreJoinPosition())) {
                String[] split = empInfoDO.getPreJoinPosition().split(",");
                String positionName = "";
                for (String depId : split) {
                    PositionInfoVO positionInfoVO = positionInfoService.selectById(depId, tokenUser.getSiteId());
                    if (positionInfoVO == null) {
                        continue;
                    }
                    String parentId = positionInfoVO.getParentId();
                    positionName = positionInfoVO.getName();
                    // 导出岗位与新增保持一致
                    for (Integer level = positionInfoVO.getLevel(); level > 3; level--) {
                        // 父级部门
                        PositionInfoVO parentPositionInfoVO = positionInfoService.selectById(parentId, tokenUser.getSiteId());
                        if (parentPositionInfoVO == null) {
                            positionName = "";
                            break;
                        }
                        positionName = parentPositionInfoVO.getName() + "/" + positionName;
                        parentId = parentPositionInfoVO.getParentId();
                    }
                    break;
                }
                oneDate.add(positionName);
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getWorkCity());
            oneDate.add(empInfoDO.getJoinCityName());
            oneDate.add(empInfoDO.getContractSubject());
            oneDate.add(empInfoDO.getArchivesNumber());
            oneDate.add(empInfoDO.getArchivesRemake());
            if (empInfoDO.getRetirementStatus() != null) {
                oneDate.add(empInfoDO.getRetirementStatus() ? "是" : "否");
            } else {
                oneDate.add("");
            }
            if (empInfoDO.getRetirementDate() != null) {
                oneDate.add(DateKit8.format(empInfoDO.getRetirementDate(), "yyyy-MM-dd"));
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getRetirementRemark());
            oneDate.add(empInfoDO.getBankCard());
            oneDate.add(empInfoDO.getBankName());
            if (StrKit.isNotEmpty(empInfoDO.getBankPlace())) {
                String bankPlaceIds = empInfoDO.getBankPlace();
                String bankPlaceName = adminProviderService.getAreaNameByIds(bankPlaceIds);
                if (StrKit.isNotEmpty(bankPlaceName)) {
                    oneDate.add(bankPlaceName);
                } else {
                    oneDate.add("");
                }
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getBankCardBranch());
            if (empInfoDO.getIsFirstSoc() != null) {
                oneDate.add(empInfoDO.getIsFirstSoc() ? "是" : "否");
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getSocCard());
            if (empInfoDO.getIsFirstPf() != null) {
                oneDate.add(empInfoDO.getIsFirstPf() ? "是" : "否");
            } else {
                oneDate.add("");
            }
            oneDate.add(empInfoDO.getPfCard());
            oneDate.add(empInfoDO.getEducation());
            // 每个员工的自定义字段
            List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empAdditionalFieldsService
                    .selectByFiledIdsAndEmpId(new ArrayList<>(fieldIdNameMap.keySet()), empInfoDO.getId());
            // 自定义字段-值
            Map<Long, String> fieldIdContentMap = empAdditionalFieldsDOList.stream().peek(empAdditionalFieldsDO -> {
                if (empAdditionalFieldsDO.getContent() == null) {
                    empAdditionalFieldsDO.setContent("");
                }
            }).collect(Collectors.toMap(EmpAdditionalFieldsDO::getFieldId, EmpAdditionalFieldsDO::getContent, (k1, k2) -> k1));
            for (Long fieldId : fieldIdNameMap.keySet()) {
                CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO = idFieldMap.get(fieldId);
                if (companyAdditionalFieldsListVO != null) {
                    String content = fieldIdContentMap.get(fieldId);
                    // 自定义字段是地区类型
                    if (Objects.equals(FIELD_TYPE_AREA, companyAdditionalFieldsListVO.getFieldType())) {
                        content = adminProviderService.getAreaNameByIds(content);
                    }
                    if (StrKit.isEmpty(content)) {
                        content = "";
                    }
                    oneDate.add(content);
                }
            }
            dataList.add(oneDate);
        }
        // 指定标红色的列
        List<Integer> columns = Collections.singletonList(1);
        // 指定批注
        HashMap<Integer, String> annotationsMap = new HashMap<>();
        annotationsMap.put(0, "姓名：可修改");
        annotationsMap.put(1, "身份证号：该列为必填项；请填写花名册中已有员工的身份证号");
//        annotationsMap.put(2, "工作性质：劳务派遣、外包、社保代缴、薪资代发");
        annotationsMap.put(2, postTypeStr);
        annotationsMap.put(3, "入职日期：格式为YYYY-MM-DD");
        annotationsMap.put(6, "婚姻状况：已婚、未婚、离异");
        annotationsMap.put(7, "生育状况：已育、未生育");
        annotationsMap.put(8, "民族：\n" +
                "汉族,阿昌族,白族,保安族,\n" +
                "布朗族,布依族,朝鲜族,\n" +
                "穿青人,傣族,达斡尔族,\n" +
                "德昂族,侗族,东乡族,\n" +
                "独龙族,鄂伦春族,俄罗斯族,\n" +
                "鄂温克族,高山族,亻革家人,\n" +
                "仡佬族,哈尼族,哈萨克族,\n" +
                "赫哲族,回族,景颇族,\n" +
                "京族,基诺族,柯尔克孜族,\n" +
                "拉祜族,黎族,傈僳族,\n" +
                "珞巴族,满族,毛南族,\n" +
                "蒙古族,门巴族,苗族,\n" +
                "仫佬族,纳西族,怒族,\n" +
                "普米族,羌族,撒拉族,\n" +
                "畲族,水族,塔吉克族,\n" +
                "塔塔尔族,土家族,土族,\n" +
                "佤族,维吾尔族,乌孜别克族,\n" +
                "锡伯族,瑶族,彝族,裕固族,\n" +
                "藏族,壮族\n");
        annotationsMap.put(9, "政治面貌：中共党员、积极分子、预备党员、共青团员、普通居民/群众、其它");
        annotationsMap.put(10, "户口类型：城镇户口、农村户口、居民户口");
        annotationsMap.put(12, "血型：A、B、AB、O、其他");
        annotationsMap.put(15, "渠道来源：需填写平台中已创建的渠道来源名称");
        annotationsMap.put(17, "试用期：填写整数天数，只填数字。例：90");
        annotationsMap.put(18, "转正日期：格式为YYYY-MM-DD");
        annotationsMap.put(20, "仅可导入一个部门，多级部门需用“/”分割。格式为：部门2/部门3；例：风控部/风控附属部");
        annotationsMap.put(21, "岗位：仅可导入一个岗位。为岗位区分类型时，格式为：类型1/岗位1；例：产品岗/产品助理。不区分类型时，格式为：岗位2；例：开发工程师，此时为默认类型");
        annotationsMap.put(23, "入职城市：填写格式为：某省/某市/某区或县。例：山东省/德州市/德城区");
        annotationsMap.put(27, "退休日期：格式为YYYY-MM-DD");
        annotationsMap.put(31, "工资卡开户城市：填写格式为：某省/某市/某区或县。例：山东省/德州市/德城区");
        HashMap<Integer, String[]> dropDownMap = new HashMap<>();
        // 指定下拉框
//        String[] postType = {"劳务派遣", "外包", "社保代缴", "薪资代发"};
        String[] postType = new String[postTypeKeyList.size()];
        postTypeKeyList.toArray(postType);
        String[] maritalStatus = {"已婚", "未婚", "离异"};
        String[] birthStatus = {"已育", "未生育"};
        String[] nation = {"汉族", "阿昌族", "白族", "保安族", "布朗族", "布依族", "朝鲜族", "穿青人", "傣族", "达斡尔族"
                , "德昂族", "侗族", "东乡族", "独龙族", "鄂伦春族", "俄罗斯族", "鄂温克族", "高山族", "亻革家人", "仡佬族", "哈尼族"
                , "哈萨克族", "赫哲族", "回族", "景颇族", "京族", "基诺族", "柯尔克孜族", "拉祜族", "黎族", "傈僳族", "珞巴族"
                , "满族", "毛南族", "蒙古族", "门巴族", "苗族", "仫佬族", "纳西族", "怒族", "普米族", "羌族", "撒拉族"
                , "畲族", "水族", "塔吉克族", "塔塔尔族", "土家族", "土族", "佤族", "维吾尔族", "乌孜别克族", "锡伯族", "瑶族"
                , "彝族", "裕固族", "藏族", "壮族"};
        String[] politicalStatus = {"中共党员", "积极分子", "预备党员", "共青团员", "普通居民/群众", "其它"};
        String[] regType = {"城镇户口", "农村户口", "居民户口"};
        String[] bloodGroup = {"A", "B", "AB", "O", "其他"};
        String[] formalType = {"无状态", "试用", "正式", "实习"};
        String[] retirementStatus = {"是", "否"};
        String[] isFirstSoc = {"是", "否"};
        String[] isFirstPf = {"是", "否"};
        if (JIA_FANG_SY.equals(site.getSiteType()) || JIA_FANG_QY.equals(site.getSiteType())) {
            dropDownMap.put(5, maritalStatus);
            dropDownMap.put(6, birthStatus);
            dropDownMap.put(7, nation);
            dropDownMap.put(8, politicalStatus);
            dropDownMap.put(9, regType);
            dropDownMap.put(11, bloodGroup);
            dropDownMap.put(15, formalType);
            dropDownMap.put(25, retirementStatus);
            dropDownMap.put(32, isFirstSoc);
            dropDownMap.put(34, isFirstPf);
        } else {

            dropDownMap.put(2, postType);
            dropDownMap.put(6, maritalStatus);
            dropDownMap.put(7, birthStatus);
            dropDownMap.put(8, nation);
            dropDownMap.put(9, politicalStatus);
            dropDownMap.put(10, regType);
            dropDownMap.put(12, bloodGroup);
            dropDownMap.put(16, formalType);
            dropDownMap.put(26, retirementStatus);
            dropDownMap.put(33, isFirstSoc);
            dropDownMap.put(35, isFirstPf);
        }

        // 表头样式
        TitleHandler titleHandler = new TitleHandler(columns, IndexedColors.RED.index, annotationsMap, dropDownMap);
        // 导出excel
        return ExcelKit.writeExcelWithModel("员工数据", dataList, headList, false, "员工数据", titleHandler);
    }


    /**
     * 根据查询参数，构建example
     *
     * @param empInfoQuery 查询参数
     * @param tokenUser    当前用户
     * @return example
     */
    private Example buildExample(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if (empInfoQuery.getCertificateType() != null) {
            example.and().andEqualTo("certificateType", empInfoQuery.getCertificateType());
        }
        if (empInfoQuery.getEmpAge() != null) {
            example.and().andEqualTo("empAge", empInfoQuery.getEmpAge());
        }
        if (empInfoQuery.getUserId() != null) {
            example.and().andEqualTo("userId", empInfoQuery.getUserId());
        }
        if (empInfoQuery.getUnionId() != null) {
            example.and().andEqualTo("unionId", empInfoQuery.getUnionId());
        }
        if (empInfoQuery.getPreJoinDep() != null) {
            example.and().andEqualTo("preJoinDep", empInfoQuery.getPreJoinDep());
        }
        if (empInfoQuery.getPreJoinPosition() != null) {
            example.and().andEqualTo("preJoinPosition", empInfoQuery.getPreJoinPosition());
        }
        if (empInfoQuery.getIdList() != null) {
            example.and().andIn("id", empInfoQuery.getIdList());
        }
        if (empInfoQuery.getContractsStatus() != null) {
            example.and().andEqualTo("contractsStatus", empInfoQuery.getContractsStatus());
        }
        if (empInfoQuery.getNumber() != null) {
            example.and().andLike("number", "%" + empInfoQuery.getNumber() + "%");
        }
        if (empInfoQuery.getName() != null) {
            example.and().andLike("name", "%" + empInfoQuery.getName() + "%");
        }
        if (empInfoQuery.getNamePinyin() != null) {
            example.and().andEqualTo("namePinyin", empInfoQuery.getNamePinyin());
        }
        if (empInfoQuery.getIdCard() != null) {
            example.and().andEqualTo("idCard", empInfoQuery.getIdCard());
        }
        if (empInfoQuery.getNation() != null) {
            example.and().andLike("nation", "%" + empInfoQuery.getNation() + "%");
        }
        if (empInfoQuery.getBirthdayStart() != null &&
                empInfoQuery.getBirthdayEnd() != null) {
            example.and().andBetween("birthday", empInfoQuery.getBirthdayStart(),
                    empInfoQuery.getBirthdayEnd());
        }
        if (empInfoQuery.getGender() != null) {
            example.and().andEqualTo("gender", empInfoQuery.getGender());
        }
        if (empInfoQuery.getContractSubject() != null) {
            example.and().andLike("contractSubject", "%" + empInfoQuery.getContractSubject() + "%");
        }
        if (empInfoQuery.getPhone() != null) {
            example.and().andLike("phone", "%" + empInfoQuery.getPhone() + "%");
        }
        if (empInfoQuery.getEmail() != null) {
            example.and().andLike("email", "%" + empInfoQuery.getEmail() + "%");
        }
        if (empInfoQuery.getEmpPhoto() != null) {
            example.and().andLike("empPhoto", "%" + empInfoQuery.getEmpPhoto() + "%");
        }
        if (empInfoQuery.getHighestEducation() != null) {
            EducationLevelEnum eduLevelEnum = EducationLevelEnum.findByDesc(empInfoQuery.getHighestEducation());
            if (eduLevelEnum != null) {
                example.and().andCondition(" id IN (SELECT emp_id FROM hr_emp_education" +
                        " WHERE education = " + eduLevelEnum.getValue() + "" +
                        " AND is_first_edu = TRUE" +
                        " AND site_id = '" + tokenUser.getSiteId() + "'" +
                        " AND company_id = '" + empInfoQuery.getCompanyId() + "')");
            }
        }
        if (empInfoQuery.getMaritalStatus() != null) {
            example.and().andLike("maritalStatus", "%" + empInfoQuery.getMaritalStatus() + "%");
        }
        if (empInfoQuery.getBirthStatus() != null) {
            example.and().andEqualTo("birthStatus", empInfoQuery.getBirthStatus());
        }
        if (empInfoQuery.getChannelId() != null) {
            example.and().andEqualTo("channelId", empInfoQuery.getChannelId());
        }
        if (empInfoQuery.getPoliticalStatus() != null) {
            example.and().andLike("politicalStatus", "%" + empInfoQuery.getPoliticalStatus() + "%");
        }
        if (empInfoQuery.getPartyDateStart() != null &&
                empInfoQuery.getPartyDateEnd() != null) {
            example.and().andBetween("partyDate", DateKit8.getStartTime(empInfoQuery.getPartyDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getPartyDateEnd()));
        }
        if (empInfoQuery.getPartySite() != null) {
            example.and().andEqualTo("partySite", empInfoQuery.getPartySite());
        }
        if (empInfoQuery.getBirthplace() != null) {
            example.and().andLike("birthplace", "%" + empInfoQuery.getBirthplace() + "%");
        }
        if (empInfoQuery.getNativeLocation() != null) {
            example.and().andLike("nativeLocation", "%" + empInfoQuery.getNativeLocation() + "%");
        }
        if (empInfoQuery.getRegType() != null) {
            example.and().andEqualTo("regType", empInfoQuery.getRegType());
        }
        if (empInfoQuery.getCurrentAddrId() != null) {
            example.and().andLike("currentAddrId", "%" + empInfoQuery.getCurrentAddrId() + "%");
        }
        if (empInfoQuery.getCurrentLocation() != null) {
            example.and().andLike("currentLocation", "%" + empInfoQuery.getCurrentLocation() + "%");
        }
        if (empInfoQuery.getCompanyId() != null && CollectionUtils.isEmpty(empInfoQuery.getCompanyIdList())) {
            example.and().andEqualTo("companyId", empInfoQuery.getCompanyId());
        }
        if (!CollectionUtils.isEmpty(empInfoQuery.getCompanyIdList())) {
            example.and().andIn("companyId", empInfoQuery.getCompanyIdList());
        }
        if (empInfoQuery.getBankCard() != null) {
            example.and().andLike("bankCard", "%" + empInfoQuery.getBankCard() + "%");
        }
        if (empInfoQuery.getBankName() != null) {
            example.and().andLike("bankName", "%" + empInfoQuery.getBankName() + "%");
        }
        if (empInfoQuery.getBankCardBranch() != null) {
            example.and().andEqualTo("bankCardBranch", empInfoQuery.getBankCardBranch());
        }
        if (empInfoQuery.getBankPlaceId() != null) {
            example.and().andLike("bankPlaceId", "%" + empInfoQuery.getBankPlaceId() + "%");
        }
        if (empInfoQuery.getBankPlace() != null) {
            example.and().andLike("bankPlace", "%" + empInfoQuery.getBankPlace() + "%");
        }
        if (empInfoQuery.getSocType() != null) {
            example.and().andEqualTo("socType", empInfoQuery.getSocType());
        }
        if (empInfoQuery.getIsFirstSoc() != null) {
            example.and().andEqualTo("isFirstSoc", empInfoQuery.getIsFirstSoc());
        }
        if (empInfoQuery.getSocCard() != null) {
            example.and().andLike("socCard", "%" + empInfoQuery.getSocCard() + "%");
        }
        if (empInfoQuery.getIsFirstPf() != null) {
            example.and().andEqualTo("isFirstPf", empInfoQuery.getIsFirstPf());
        }
        if (empInfoQuery.getPfCard() != null) {
            example.and().andEqualTo("pfCard", empInfoQuery.getPfCard());
        }
        if (empInfoQuery.getHealthCondition() != null) {
            example.and().andEqualTo("healthCondition", empInfoQuery.getHealthCondition());
        }
        if (empInfoQuery.getHasWeightyMedicalHis() != null) {
            example.and().andEqualTo("hasWeightyMedicalHis", empInfoQuery.getHasWeightyMedicalHis());
        }
        if (empInfoQuery.getJobTitle() != null) {
            example.and().andEqualTo("jobTitle", empInfoQuery.getJobTitle());
        }
        if (empInfoQuery.getJoinWorkDateStart() != null &&
                empInfoQuery.getJoinWorkDateEnd() != null) {
            example.and().andBetween("joinWorkDate", DateKit8.getStartTime(empInfoQuery.getJoinWorkDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getJoinWorkDateEnd()));
        }
        if (empInfoQuery.getWorkingUnitName() != null) {
            example.and().andEqualTo("workingUnitName", empInfoQuery.getWorkingUnitName());
        }
        if (empInfoQuery.getPutonghuaLevel() != null) {
            example.and().andEqualTo("putonghuaLevel", empInfoQuery.getPutonghuaLevel());
        }
        if (empInfoQuery.getSpeciality() != null) {
            example.and().andEqualTo("speciality", empInfoQuery.getSpeciality());
        }
        if (empInfoQuery.getPrizeWinning() != null) {
            example.and().andEqualTo("prizeWinning", empInfoQuery.getPrizeWinning());
        }
        if (empInfoQuery.getEnglishLevel() != null) {
            example.and().andEqualTo("englishLevel", empInfoQuery.getEnglishLevel());
        }
        if (empInfoQuery.getNcreLevel() != null) {
            example.and().andEqualTo("ncreLevel", empInfoQuery.getNcreLevel());
        }
        if (empInfoQuery.getTargetPost() != null) {
            example.and().andEqualTo("targetPost", empInfoQuery.getTargetPost());
        }
        if (empInfoQuery.getAnnexIdCard() != null) {
            example.and().andEqualTo("annexIdCard", empInfoQuery.getAnnexIdCard());
        }
        if (empInfoQuery.getAnnexHousehold() != null) {
            example.and().andEqualTo("annexHousehold", empInfoQuery.getAnnexHousehold());
        }
        if (empInfoQuery.getAnnexDiploma() != null) {
            example.and().andEqualTo("annexDiploma", empInfoQuery.getAnnexDiploma());
        }
        if (empInfoQuery.getAnnexDegree() != null) {
            example.and().andEqualTo("annexDegree", empInfoQuery.getAnnexDegree());
        }
        if (empInfoQuery.getAnnexPractising() != null) {
            example.and().andEqualTo("annexPractising", empInfoQuery.getAnnexPractising());
        }
        if (empInfoQuery.getAnnexMajor() != null) {
            example.and().andEqualTo("annexMajor", empInfoQuery.getAnnexMajor());
        }
        if (empInfoQuery.getAnnexReward() != null) {
            example.and().andEqualTo("annexReward", empInfoQuery.getAnnexReward());
        }
        if (empInfoQuery.getAnnexNoCriminal() != null) {
            example.and().andEqualTo("annexNoCriminal", empInfoQuery.getAnnexNoCriminal());
        }
        if (empInfoQuery.getAnnexBlackWhitePhoto() != null) {
            example.and().andEqualTo("annexBlackWhitePhoto", empInfoQuery.getAnnexBlackWhitePhoto());
        }
        if (empInfoQuery.getAnnexPthLevel() != null) {
            example.and().andEqualTo("annexPthLevel", empInfoQuery.getAnnexPthLevel());
        }
        if (empInfoQuery.getAnnexEnglishLevel() != null) {
            example.and().andEqualTo("annexEnglishLevel", empInfoQuery.getAnnexEnglishLevel());
        }
        if (empInfoQuery.getAnnexNcreLevel() != null) {
            example.and().andEqualTo("annexNcreLevel", empInfoQuery.getAnnexNcreLevel());
        }
        if (empInfoQuery.getAnnexDrivingLicense() != null) {
            example.and().andEqualTo("annexDrivingLicense", empInfoQuery.getAnnexDrivingLicense());
        }
        if (empInfoQuery.getAnnexPersonPhoto() != null) {
            example.and().andEqualTo("annexPersonPhoto", empInfoQuery.getAnnexPersonPhoto());
        }
        if (empInfoQuery.getAnnexSalaryCard() != null) {
            example.and().andEqualTo("annexSalaryCard", empInfoQuery.getAnnexSalaryCard());
        }
        if (empInfoQuery.getAnnexSocCard() != null) {
            example.and().andEqualTo("annexSocCard", empInfoQuery.getAnnexSocCard());
        }
        if (empInfoQuery.getAnnexPfCard() != null) {
            example.and().andEqualTo("annexPfCard", empInfoQuery.getAnnexPfCard());
        }
        if (empInfoQuery.getAnnexLaborContract() != null) {
            example.and().andEqualTo("annexLaborContract", empInfoQuery.getAnnexLaborContract());
        }
        if (empInfoQuery.getAnnexOnbResume() != null) {
            example.and().andEqualTo("annexOnbResume", empInfoQuery.getAnnexOnbResume());
        }
        if (empInfoQuery.getAnnexOnbCheckup() != null) {
            example.and().andEqualTo("annexOnbCheckup", empInfoQuery.getAnnexOnbCheckup());
        }
        if (empInfoQuery.getAnnexLastLeaveCert() != null) {
            example.and().andEqualTo("annexLastLeaveCert", empInfoQuery.getAnnexLastLeaveCert());
        }
        if (empInfoQuery.getAnnexWorkApply() != null) {
            example.and().andEqualTo("annexWorkApply", empInfoQuery.getAnnexWorkApply());
        }
        if (empInfoQuery.getAnnexAdjustNotice() != null) {
            example.and().andEqualTo("annexAdjustNotice", empInfoQuery.getAnnexAdjustNotice());
        }
        if (empInfoQuery.getAnnexPersonalChange() != null) {
            example.and().andEqualTo("annexPersonalChange", empInfoQuery.getAnnexPersonalChange());
        }
        if (empInfoQuery.getAnnexSocTransfer() != null) {
            example.and().andEqualTo("annexSocTransfer", empInfoQuery.getAnnexSocTransfer());
        }
        if (empInfoQuery.getAnnexPerformanceReport() != null) {
            example.and().andEqualTo("annexPerformanceReport", empInfoQuery.getAnnexPerformanceReport());
        }
        if (empInfoQuery.getAnnexOtherInfos() != null) {
            example.and().andEqualTo("annexOtherInfos", empInfoQuery.getAnnexOtherInfos());
        }
        if (empInfoQuery.getAnnexLeaveAppro() != null) {
            example.and().andEqualTo("annexLeaveAppro", empInfoQuery.getAnnexLeaveAppro());
        }
        if (empInfoQuery.getAnnexLeaveCert() != null) {
            example.and().andEqualTo("annexLeaveCert", empInfoQuery.getAnnexLeaveCert());
        }
        if (empInfoQuery.getAnnexLeaveApply() != null) {
            example.and().andEqualTo("annexLeaveApply", empInfoQuery.getAnnexLeaveApply());
        }
        if (empInfoQuery.getAnnexHandoverTable() != null) {
            example.and().andEqualTo("annexHandoverTable", empInfoQuery.getAnnexHandoverTable());
        }
        if (empInfoQuery.getSupervisor() != null) {
            example.and().andLike("supervisor", "%" + empInfoQuery.getSupervisor() + "%");
        }
        if (empInfoQuery.getEmployType() != null) {
            example.and().andEqualTo("employType", empInfoQuery.getEmployType());
        }
        if (empInfoQuery.getInformalType() != null) {
            example.and().andEqualTo("informalType", empInfoQuery.getInformalType());
        }
        if (empInfoQuery.getFormalType() != null) {
            example.and().andEqualTo("formalType", empInfoQuery.getFormalType());
        }
        if (empInfoQuery.getIsImprove() != null) {
            example.and().andEqualTo("isImprove", empInfoQuery.getIsImprove());
        }
        if (empInfoQuery.getPostType() != null) {
            example.and().andEqualTo("postType", empInfoQuery.getPostType());
        }
        if (empInfoQuery.getManagerForm() != null) {
            example.and().andEqualTo("managerForm", empInfoQuery.getManagerForm());
        }
        if (empInfoQuery.getWorkCityId() != null) {
            example.and().andLike("workCityId", "%" + empInfoQuery.getWorkCityId() + "%");
        }
        if (empInfoQuery.getWorkCity() != null) {
            example.and().andLike("workCity", "%" + empInfoQuery.getWorkCity() + "%");
        }
        if (empInfoQuery.getJoinFormStatus() != null) {
            example.and().andEqualTo("joinFormStatus", empInfoQuery.getJoinFormStatus());
        }
        if (empInfoQuery.getPreJoinDateStart() != null &&
                empInfoQuery.getPreJoinDateEnd() != null) {
            example.and().andBetween("preJoinDate", DateKit8.getStartTime(empInfoQuery.getPreJoinDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getPreJoinDateEnd()));
        }
        if (empInfoQuery.getJoinDateStart() != null &&
                empInfoQuery.getJoinDateEnd() != null) {
            example.and().andBetween("joinDate", DateKit8.getStartTime(empInfoQuery.getJoinDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getJoinDateEnd()));
        }
        if (empInfoQuery.getProbation() != null) {
            example.and().andEqualTo("probation", empInfoQuery.getProbation());
        }
        if (empInfoQuery.getProbationDays() != null) {
            example.and().andEqualTo("probationDays", empInfoQuery.getProbationDays());
        }
        if (empInfoQuery.getTurnStraightDateStart() != null &&
                empInfoQuery.getTurnStraightDateEnd() != null) {
            example.and().andBetween("turnStraightDate", DateKit8.getStartTime(empInfoQuery.getTurnStraightDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getTurnStraightDateEnd()));
        }
        if (empInfoQuery.getLeaveDateStart() != null &&
                empInfoQuery.getLeaveDateEnd() != null) {
            example.and().andBetween("leaveDate", DateKit8.getStartTime(empInfoQuery.getLeaveDateStart()),
                    DateKit8.getEndTime(empInfoQuery.getLeaveDateEnd()));
        }
        if (empInfoQuery.getLeaveReason() != null) {
            example.and().andLike("leaveReason", "%" + empInfoQuery.getLeaveReason() + "%");
        }
        if (empInfoQuery.getChangeStatus() != null) {
            example.and().andEqualTo("changeStatus", empInfoQuery.getChangeStatus());
        }
        if (empInfoQuery.getVerified() != null) {
            example.and().andEqualTo("verified", empInfoQuery.getVerified());
        }
        if (empInfoQuery.getStatus() != null) {
            example.and().andEqualTo("status", empInfoQuery.getStatus());
        }
        if (empInfoQuery.getApprovalStatus() != null) {
            example.and().andEqualTo("approvalStatus", empInfoQuery.getApprovalStatus());
        }
        if (empInfoQuery.getJoinCityCode() != null && CollectionUtils.isEmpty(empInfoQuery.getJoinCityCodeList())) {
            example.and().andEqualTo("joinCityCode", empInfoQuery.getJoinCityCode());
        }
        if (!CollectionUtils.isEmpty(empInfoQuery.getJoinCityCodeList())) {
            example.and().andIn("joinCityCode", empInfoQuery.getJoinCityCodeList());
        }

        if (empInfoQuery.getJoinCityName() != null) {
            example.and().andEqualTo("joinCityName", empInfoQuery.getJoinCityName());
        }
        if (empInfoQuery.getArchivesNumber() != null) {
            example.and().andEqualTo("archivesNumber", empInfoQuery.getArchivesNumber());
        }
        if (empInfoQuery.getArchivesRemake() != null) {
            example.and().andEqualTo("archivesRemake", empInfoQuery.getArchivesRemake());
        }
        if (empInfoQuery.getRecruitChannels() != null) {
            example.and().andEqualTo("recruitChannels", empInfoQuery.getRecruitChannels());
        }
        if (empInfoQuery.getRetirementStatus() != null) {
            example.and().andEqualTo("retirementStatus", empInfoQuery.getRetirementStatus());
        }
        if (empInfoQuery.getRetirementDate() != null) {
            example.and().andEqualTo("retirementDate", empInfoQuery.getRetirementDate());
        }
        if (empInfoQuery.getRetirementRemark() != null) {
            example.and().andEqualTo("retirementRemark", empInfoQuery.getRetirementRemark());
        }
        if (empInfoQuery.getBloodGroup() != null) {
            example.and().andEqualTo("bloodGroup", empInfoQuery.getBloodGroup());
        }
        if (empInfoQuery.getAlipayAccount() != null) {
            example.and().andEqualTo("alipayAccount", empInfoQuery.getAlipayAccount());
        }
        if (empInfoQuery.getSalaryRuleId() != null) {
            example.and().andEqualTo("salaryRuleId", empInfoQuery.getSalaryRuleId());
        }
        if (empInfoQuery.getServiceFeeRuleId() != null) {
            example.and().andEqualTo("serviceFeeRuleId", empInfoQuery.getServiceFeeRuleId());
        }
        if (empInfoQuery.getGmtCreateStart() != null &&
                empInfoQuery.getGmtCreateEnd() != null) {
            example.and().andBetween("gmtCreate", empInfoQuery.getGmtCreateStart(),
                    empInfoQuery.getGmtCreateEnd());
        }
        if (empInfoQuery.getCreateUserId() != null) {
            example.and().andLike("createUserId", "%" + empInfoQuery.getCreateUserId() + "%");
        }
        if (empInfoQuery.getGmtModifiedStart() != null &&
                empInfoQuery.getGmtModifiedEnd() != null) {
            example.and().andBetween("gmtModified", empInfoQuery.getGmtModifiedStart(),
                    empInfoQuery.getGmtModifiedEnd());
        }
        if (empInfoQuery.getModifiedUserId() != null) {
            example.and().andLike("modifiedUserId", "%" + empInfoQuery.getModifiedUserId() + "%");
        }
        if (StringUtils.isNotBlank(empInfoQuery.getNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empInfoQuery.getNameOrPhone() + "%");
        }
        if (empInfoQuery.getDepId() != null) {
            if (!("-1".equals(empInfoQuery.getDepId()))) {
                example.and().andCondition("id in (select emp_id from hr_emp_dep where dep_id = '" + empInfoQuery.getDepId() + "')");
            } else {
                example.and().andIsNull("preJoinDep").orEqualTo("preJoinDep", "");
            }
        }
        if (empInfoQuery.getPositionId() != null) {
            example.and().andCondition("id in (select emp_id from hr_emp_position where position_id = '" + empInfoQuery.getPositionId() + "')");
        }
        if (!StringUtils.isEmpty(empInfoQuery.getNameOrPhoneOrEmail())) {
            example.and()
                    .orLike("name", "%" + empInfoQuery.getNameOrPhoneOrEmail() + "%")
                    .orLike("idCard", "%" + empInfoQuery.getNameOrPhoneOrEmail() + "%")
                    .orLike("phone", "%" + empInfoQuery.getNameOrPhoneOrEmail() + "%")
                    .orLike("email", "%" + empInfoQuery.getNameOrPhoneOrEmail() + "%");
        }
        // 排序
        ExampleKit.setExampleOrder(example, empInfoQuery.getOrders());
        return example;
    }

    /**
     * 判断一个公司是不是子公司
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @return true:是子公司,false:不是子公司
     */
    private boolean checkIsChildCompany(String companyId, TokenUser tokenUser) {
        if (StringUtils.isEmpty(companyId)) {
            return false;
        }
        if (StringUtils.isNotEmpty(tokenUser.getUserId())) {
            // 用户是不是admin
            boolean userIsAdmin = hrPermissionService.isAdmin(tokenUser.getUserId(), tokenUser.getSiteId());
            // 用户是不是总公司的成员
            boolean userIsSuperCompany = hrPermissionService.isSuperCompanyAdmin(tokenUser.getUserId(), tokenUser.getSiteId());

            if (userIsAdmin || userIsSuperCompany) {
                return false;
            }
        }

        List<String> groupIdList = groupCompanyService.checkCompanyIsChild(companyId, tokenUser.getSiteId());
        return !CollectionUtils.isEmpty(groupIdList);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoCountVO getEmpInfoCount(String companyId, TokenUser tokenUser) {
        EmpInfoCountVO empInfoCount = new EmpInfoCountVO();

        // 获取本公司用户全部可见的员工
        List<EmpInfoDO> empInfoList = listByCompanyAndUser(companyId, tokenUser);

        // 根据员工状态分组
        Map<Integer, List<EmpInfoDO>> statusMap = empInfoList.parallelStream()
                .collect(Collectors.groupingBy(EmpInfoDO::getStatus));

        // 待入职员工(尚未确认到岗的)
        List<EmpInfoDO> preEmpInfoList = statusMap.containsKey(1) ? statusMap.get(1) : new ArrayList<>();

        // 在职员工
        List<EmpInfoDO> workEmpInfoList = statusMap.containsKey(2) ? statusMap.get(2) : new ArrayList<>();

        // 待离职
        List<EmpInfoDO> waitLeaveEmpInfoList = statusMap.containsKey(3) ? statusMap.get(3) : new ArrayList<>();

        // 已离职
        List<EmpInfoDO> leaveEmpInfoList = statusMap.containsKey(4) ? statusMap.get(4) : new ArrayList<>();

        // 在职(在职+待离职)
        List<EmpInfoDO> onJobEmpInfoList = new ArrayList<>(workEmpInfoList);
        onJobEmpInfoList.addAll(waitLeaveEmpInfoList);

        // 全部员工(只要没确认离职的都算)
        empInfoCount.setCountAll(preEmpInfoList.size() + onJobEmpInfoList.size());

        // 全部在职员工(确认到岗,没确认离职的都算)
        empInfoCount.setCountOnJob(onJobEmpInfoList.size());

        // 待入职员工(尚未确认到岗的)
        empInfoCount.setCountPre(preEmpInfoList.size());

        // 待转正(确认到岗后,未转正的)
        List<EmpInfoDO> onJobWaitFormalEmpInfoList = onJobEmpInfoList.parallelStream()
                .filter(empInfo -> PROBATION.getValue().equals(empInfo.getFormalType()))
                .collect(Collectors.toList());
        empInfoCount.setCountWaitInformalAll(onJobWaitFormalEmpInfoList.size());

        // 待转正(确认到岗后,未转正的,不包含待离职的)
        List<EmpInfoDO> workWaitFormalEmpInfoList = workEmpInfoList.parallelStream()
                .filter(empInfo -> PROBATION.getValue().equals(empInfo.getFormalType()))
                .collect(Collectors.toList());
        empInfoCount.setCountWaitInformalOn(workWaitFormalEmpInfoList.size());

        // 已转正(确认到岗后,已转正的)
        List<EmpInfoDO> onJobHasFormalEmpInfoList = onJobEmpInfoList.parallelStream()
                .filter(empInfo -> FormalTypeEnum.FORMAL.getValue().equals(empInfo.getFormalType()))
                .collect(Collectors.toList());
        empInfoCount.setCountHasInformalAll(onJobHasFormalEmpInfoList.size());

        // 已转正(确认到岗后,已转正的,不包含待离职的)
        List<EmpInfoDO> workHasFormalEmpInfoList = workEmpInfoList.parallelStream()
                .filter(empInfo -> FormalTypeEnum.FORMAL.getValue().equals(empInfo.getFormalType()) && empInfo.getChangeStatus() != 2)
                .collect(Collectors.toList());
        empInfoCount.setCountHasInformalOn(workHasFormalEmpInfoList.size());

        // 离职全部的(包含待离职,已离职)
        empInfoCount.setCountLeaveAll(waitLeaveEmpInfoList.size() + leaveEmpInfoList.size());

        // 待离职
        empInfoCount.setCountLeaveOn(waitLeaveEmpInfoList.size());

        // 已离职
        empInfoCount.setCountLeaveHas(leaveEmpInfoList.size());

        // 调岗中
        List<EmpInfoDO> onJobChangeEmpInfoList = onJobEmpInfoList.parallelStream()
                .filter(empInfo -> empInfo.getChangeStatus() == 2)
                .collect(Collectors.toList());
        empInfoCount.setCountChange(onJobChangeEmpInfoList.size());

        // 无正式状态员工
//        List<EmpInfoDO> onJobNoFormalEmpInfoList = onJobEmpInfoList.parallelStream()
//                .filter(empInfo -> FormalTypeEnum.NOTYPE.getValue().equals(empInfo.getFormalType()))
//                .collect(Collectors.toList());
//        empInfoCount.setCountNoStatus(onJobNoFormalEmpInfoList.size());

        // 根据员工状态分组
        Map<Integer, Long> postTypeMap = onJobEmpInfoList.parallelStream()
                .collect(Collectors.groupingBy(EmpInfoDO::getPostType, Collectors.counting()));

        // 劳务派遣
        empInfoCount.setCountLabour(postTypeMap.containsKey(PostType.LABOUR.getValue()) ? postTypeMap.get(PostType.LABOUR.getValue()).intValue() : 0);
        // 外包
        empInfoCount.setCountOutsource(postTypeMap.containsKey(PostType.OUTSOURCE.getValue()) ? postTypeMap.get(PostType.OUTSOURCE.getValue()).intValue() : 0);
        // 社保代缴
        empInfoCount.setCountSocialSecurityPayment(postTypeMap.containsKey(PostType.SOCIAL_SECURITY_PAYMENT.getValue()) ? postTypeMap.get(PostType.SOCIAL_SECURITY_PAYMENT.getValue()).intValue() : 0);
        // 薪资代发
        empInfoCount.setCountPayrollAgency(postTypeMap.containsKey(PostType.PAYROLL_AGENCY.getValue()) ? postTypeMap.get(PostType.PAYROLL_AGENCY.getValue()).intValue() : 0);
        // 其他
        empInfoCount.setCountOther(postTypeMap.containsKey(PostType.OTHER.getValue()) ? postTypeMap.get(PostType.OTHER.getValue()).intValue() : 0);

        return empInfoCount;
    }

    /**
     * 获取本公司用户全部可见的员工
     *
     * @param companyId 公司id
     * @param tokenUser 当前用户
     * @return 本公司用户全部可见的员工
     */
    private List<EmpInfoDO> listByCompanyAndUser(String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());

        return empInfoDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoPageRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        return pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(), empInfoQuery.getPageSize(), tokenUser.getSiteId());
    }

    /**
     * 将部门和岗位添加到员工身上,关联关系的
     *
     * @param empInfoListVO 员工信息
     * @param siteId        站点
     */
    private void addDepAndPositionToEmpByRelation(EmpInfoListVO empInfoListVO, String siteId) {
        if (Objects.isNull(empInfoListVO)) {
            return;
        }
        // 人员所属部门名称
        Map<String, String> depMap = listDepNameByEmp(empInfoListVO.getCompanyId(), empInfoListVO.getId(), siteId);
        //部门集合
        if (depMap.size() > 0) {
            List<String> depNameList = new ArrayList<>();
            depMap.forEach(
                    (key, value) -> depNameList.add(value)
            );
            empInfoListVO.setDepName(String.join(",", depNameList));
        }
        //  岗位集合
        Map<String, String> positionMap = listPositionNameByEmp(empInfoListVO.getCompanyId(), empInfoListVO.getId(), siteId);

        if (positionMap.size() > 0) {
            List<String> positionNameList = new ArrayList<>();
            positionMap.forEach(
                    (key, value) -> positionNameList.add(value)
            );
            empInfoListVO.setPositionName(String.join(",", positionNameList));
        }
    }

    /**
     * 人员所属部门名称
     *
     * @param companyId 公司id
     * @param empId     员工id
     * @param siteId    站点id
     * @return 人员所属部门名称
     */
    private Map<String, String> listDepNameByEmp(String companyId, String empId, String siteId) {
        //部门集合
        List<EmpDepDO> empDepList = empDepService.listAllByEmpId(companyId, empId, siteId);
        //
        Map<String, String> empDepMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empDepList)) {
            // 部门id与部门名称的接口
            Map<String, String> depMap = depInfoService.getDepIdAndNameMapByCompany(companyId, siteId);
            // 人员所属部门名称
            empDepList.parallelStream()
                    .filter(empDep -> depMap.containsKey(empDep.getDepId()))
                    .forEach(empDep ->
                            empDepMap.put(empDep.getDepId(), depMap.get(empDep.getDepId()))
                    );
        }
        return empDepMap;
    }

    /**
     * 人员所属岗位名称
     *
     * @param companyId 公司id
     * @param empId     员工id
     * @param siteId    站点id
     * @return 人员所属岗位名称
     */
    private Map<String, String> listPositionNameByEmp(String companyId, String empId, String siteId) {
        //岗位集合
        List<EmpPositionDO> empPositionList = empPositionService.listAllByEmpId(companyId, empId, siteId);
        //
        Map<String, String> empPositionMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empPositionList)) {
            // 岗位id与岗位名称的接口
            Map<String, String> positionMap = positionInfoService.getPositionIdAndNameMapByCompany(companyId, siteId);
            // 人员所属岗位名称
            empPositionList.stream()
                    .filter(empPosition -> positionMap.containsKey(empPosition.getPositionId()))
                    .forEach(empPosition ->
                            empPositionMap.put(empPosition.getPositionId(), positionMap.get(empPosition.getPositionId()))
                    );

        }
        return empPositionMap;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoPendingRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        if (!StringUtils.isEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        List<EmpInfoListVO> list = new ArrayList<>();
        if (!CollectionUtils.isEmpty(empInfoDOList)) {
            list = empInfoDOList.stream().map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        }
        Integer approvalAndStatus = empInfoQuery.getApprovalAndStatus();
        list = parseWaitJoinApproveStatusList(list, approvalAndStatus);
        Page<EmpInfoListVO> page = PageKit.startPage(list, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
        list = page.getEntities();
        if (!CollectionUtils.isEmpty(list)) {
            List<String> channelIdList = list.parallelStream().map(EmpInfoListVO::getChannelId).collect(Collectors.toList());
            List<ChannelVO> channelVOS = channelService.selectByIds(channelIdList, tokenUser.getSiteId());
            // channelId-channelVO Map
            Map<String, String> channelIdMap = channelVOS.parallelStream().collect(Collectors.toMap(ChannelVO::getId, ChannelVO::getName));
            // 部门id与部门名称的接口
            Map<String, String> depMap = depInfoService.getDepIdAndNameMapByCompany(list.get(0).getCompanyId(), tokenUser.getSiteId());
            // 岗位id与岗位名称的接口
            Map<String, String> positionMap = positionInfoService.getPositionIdAndNameMapByCompany(list.get(0).getCompanyId(), tokenUser.getSiteId());

            list.forEach(
                    empInfoListVO -> {
                        // 待入职,用准备加入的
                        // 部门
                        if (!StringUtils.isEmpty(empInfoListVO.getPreJoinDep())) {
                            String[] depIds = empInfoListVO.getPreJoinDep().split(",");

                            List<String> depNameList = Arrays.stream(depIds)
                                    .filter(depMap::containsKey)
                                    .map(depMap::get)
                                    .collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(depNameList)) {
                                empInfoListVO.setDepName(String.join(",", depNameList));
                            }
                        } else {
                            empInfoListVO.setDepName("暂无");
                        }

                        // 岗位
                        if (!StringUtils.isEmpty(empInfoListVO.getPreJoinPosition())) {
                            String[] positionIds = empInfoListVO.getPreJoinPosition().split(",");
                            List<String> positionNameList = Arrays.stream(positionIds)
                                    .filter(positionMap::containsKey)
                                    .map(positionMap::get)
                                    .collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(positionNameList)) {
                                empInfoListVO.setPositionName(String.join(",", positionNameList));
                            }
                        } else {
                            empInfoListVO.setPositionName("暂无");
                        }
                        if (StrKit.isNotEmpty(empInfoListVO.getChannelId())) {
                            empInfoListVO.setChannelName(channelIdMap.get(empInfoListVO.getChannelId()));
                        }
                    }
            );

            //查询公司所有自定义字段
            List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList =
                    companyAdditionalFieldsService.selectOpenByCompanyId(empInfoQuery.getCompanyId(), tokenUser.getSiteId());
            //员工填充自定义属性
            customAttributeFill(list, companyAdditionalFieldsListVOList);
            batchOtherHeaderAssignment(list, tokenUser);
            page.setEntities(list);
        }
        return page;
    }

    @Override
    public Page<EmpInfoListVO> pageWaitJobAdvanced(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        List<EmpInfoListVO> empInfoListVOS = selectWaitJobAdvanced(empInfoQuery, tokenUser);
        return PageKit.startPage(empInfoListVOS, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
    }

    @Override
    public List<EmpInfoListVO> selectWaitJobAdvanced(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        ParamException.hasText(empInfoQuery.getCompanyId(), "用工单位id不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", WAIT_ENTRY.getValue())
                .andEqualTo("companyId", empInfoQuery.getCompanyId());
        // 姓名/手机号/身份证
        if (StrKit.isNotEmpty(empInfoQuery.getNameOrPhone())) {
            example.and()
                    .andLike("name", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + empInfoQuery.getNameOrPhone() + "%");
        }
        // 员工标签
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        // 工作性质
        if (StrKit.isNotEmpty(empInfoQuery.getPostType())) {
            example.and()
                    .andEqualTo("postType", empInfoQuery.getPostType());
        }
        // 入职日期
        if (empInfoQuery.getJoinDateStart() != null
                && empInfoQuery.getJoinDateEnd() != null) {
            example.and()
                    .andBetween("joinDate", DateKit8.getStartTime(empInfoQuery.getJoinDateStart()),
                            DateKit8.getEndTime(empInfoQuery.getJoinDateEnd()));
        }
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return new ArrayList<>();
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        // 只支持识别待入职管理列表中状态为“待入职”“审批通过”的员工
        parseWaitJoinApproveStatusList(empInfoListVOS, null);
        // 过滤去掉不是待入职的人
        empInfoListVOS.removeIf(s -> !PENDING_RELATION.equals(s.getApprovalAndStatus()));
        return empInfoListVOS;
    }

    /**
     * 员工标签检索并去重分页查询
     *
     * @param tag      标签
     * @param example  带有其他条件的Example
     * @param pageNo   页码
     * @param pageSize 每页多少条数据
     * @return page
     */
    private Page<EmpInfoDO> tagPageList(String tag, Example example, Integer pageNo, Integer pageSize) {
        List<EmpInfoDO> empInfoDOList = tagSelect(tag, example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return new Page<>(pageSize, pageNo);
        }
        return PageKit.startPage(empInfoDOList, pageNo, pageSize);
    }

    /**
     * 员工标签检索并去重
     *
     * @param tag     标签
     * @param example 带有其他条件的Example
     * @return 查询出的员工
     */
    private List<EmpInfoDO> tagSelect(String tag, Example example) {
        List<EmpInfoDO> empInfoDOList = new ArrayList<>();
        // 处理标签检索
        if (StrKit.isNotEmpty(tag)) {
            List<String> tagList = ArrayKit.split(tag, ",");
            if (tagList.size() == 1) {
                String tagName = tagList.get(0);
                example.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                empInfoDOList = empInfoDAO.selectByExample(example);
            } else {
                // 循环tag,全部检索
                for (String tagName : tagList) {
                    Example example1 = ExampleKit.copyExample(example, EmpInfoDO.class);
                    example1.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                    List<EmpInfoDO> empInfoDOList1 = empInfoDAO.selectByExample(example1);
                    empInfoDOList.addAll(empInfoDOList1);
                    empInfoDOList = empInfoDOList.stream()
                            .filter(StreamKit.distinctByKey(EmpInfoDO::getId))
                            .collect(Collectors.toList());
                }
            }
        } else {
            empInfoDOList = empInfoDAO.selectByExample(example);
        }
        return empInfoDOList;
    }

    /**
     * 处理审批状态
     */
    private List<EmpInfoListVO> parseWaitJoinApproveStatusList(List<EmpInfoListVO> empInfoListVOS, Integer approvalStatus) {
        if (approvalStatus == null) {
            empInfoListVOS.forEach(empInfoListVO -> {
                // 审批状态
                Integer approvalStatus1 = empInfoListVO.getApprovalStatus();
                // 是否到岗
                Boolean arrival = empInfoListVO.getArrival();
                if (Boolean.FALSE.equals(arrival)) {
                    empInfoListVO.setApprovalAndStatus(NO_ARRIVAL);
                } else if (ApprovalStatusEnum.APPRO_FAIL.getValue().equals(approvalStatus1)) {
                    empInfoListVO.setApprovalAndStatus(REFUSE);
                } else if (ApprovalStatusEnum.APPRO_ING.getValue().equals(approvalStatus1)) {
                    empInfoListVO.setApprovalAndStatus(APPROVING);
                } else {
                    empInfoListVO.setApprovalAndStatus(PENDING_RELATION);
                }
            });
            return empInfoListVOS;
        }
        return empInfoListVOS.stream().map(empInfo -> {
            Integer approvalStatus1 = empInfo.getApprovalStatus();
            empInfo.setApprovalAndStatus(approvalStatus);
            // 未到岗
            if (NO_ARRIVAL.equals(approvalStatus)) {
                if (!Boolean.FALSE.equals(empInfo.getArrival())) {
                    return null;
                }
            }
            // 审批中
            else if (APPROVING.equals(approvalStatus)) {
                if (!ApprovalStatusEnum.APPRO_ING.getValue().equals(approvalStatus1)) {
                    return null;
                }
            }
            // 审批驳回
            else if (REFUSE.equals(approvalStatus)) {
                if (!ApprovalStatusEnum.APPRO_FAIL.getValue().equals(approvalStatus1)) {
                    return null;
                }
            }
            // 待入职
            else if (PENDING_RELATION.equals(approvalStatus)) {
                if (null != empInfo.getArrival()) {
                    return null;
                }
                if (ApprovalStatusEnum.APPRO_ING.getValue().equals(approvalStatus1)
                        || ApprovalStatusEnum.APPRO_FAIL.getValue().equals(approvalStatus1)) {
                    return null;
                }
            }
            return empInfo;
        }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    @Override
    public List<EmpInfoListVO> selectEmpInfoPendingRelationList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        // 查询
        empInfoQuery.setStatus(1);
        List<EmpInfoListVO> list = select(empInfoQuery, tokenUser);
        if (!CollectionUtils.isEmpty(list)) {
            // 部门id与部门名称的接口
            Map<String, String> depMap = depInfoService.getDepIdAndNameMapByCompany(list.get(0).getCompanyId(), tokenUser.getSiteId());
            // 岗位id与岗位名称的接口
            Map<String, String> positionMap = positionInfoService.getPositionIdAndNameMapByCompany(list.get(0).getCompanyId(), tokenUser.getSiteId());

            list.forEach(
                    empInfoListVO -> {
                        // 待入职,用准备加入的
                        // 部门
                        if (!StringUtils.isEmpty(empInfoListVO.getPreJoinDep())) {
                            String[] depIds = empInfoListVO.getPreJoinDep().split(",");

                            List<String> depNameList = Arrays.stream(depIds)
                                    .filter(depMap::containsKey)
                                    .map(depMap::get)
                                    .collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(depNameList)) {
                                empInfoListVO.setDepName(String.join(",", depNameList));
                            }
                        }

                        // 岗位
                        if (!StringUtils.isEmpty(empInfoListVO.getPreJoinPosition())) {
                            String[] positionIds = empInfoListVO.getPreJoinPosition().split(",");
                            List<String> positionNameList = Arrays.stream(positionIds)
                                    .filter(positionMap::containsKey)
                                    .map(positionMap::get)
                                    .collect(Collectors.toList());

                            if (!CollectionUtils.isEmpty(positionNameList)) {
                                empInfoListVO.setPositionName(String.join(",", positionNameList));
                            }
                        }
                    }
            );
        }
        return list;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoOnJobRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setFormalType(FormalTypeEnum.FORMAL.getValue());
        Example example = buildExample(empInfoQuery, tokenUser);
        example.and().andNotEqualTo("changeStatus", 2);
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        if (Boolean.TRUE.equals(empInfoQuery.getIsApproPass())) {
            example.and().andIn("approvalStatus",
                    Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                            ApprovalStatusEnum.APPRO_DISABLE.getValue()));
        }
        return pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(), empInfoQuery.getPageSize(), tokenUser.getSiteId());
    }

    @Override
    public EmpInfoPasteVO selectEmpInfoOnJobRelationByIdCards(String[] idCards, String companyId, TokenUser tokenUser) {

        List<String> idCardList = ArrayKit.asList(idCards);
        ParamException.notEmpty(idCardList, "身份证号不能为空");

        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("status", HAS_ENTRY.getValue())
                .andEqualTo("formalType", FormalTypeEnum.FORMAL.getValue())
                .andNotEqualTo("changeStatus", 2)
                .andIn("idCard", idCardList)
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                // 只查询审批通过的和不需要审批的
                .andIn("approvalStatus",
                        Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                                ApprovalStatusEnum.APPRO_DISABLE.getValue()));
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            empInfoPasteVO.setIdCardList(idCardList);
            return empInfoPasteVO;
        }
        List<EmpInfoVO> empInfoVOList = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoVO.class)).collect(Collectors.toList());
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        // 去除已查询出的身份证
        idCardList.removeAll(empInfoVOList.parallelStream().map(EmpInfoVO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public List<EmpInfoListVO> selectEmpInfoOnJobRelationList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setFormalType(FormalTypeEnum.FORMAL.getValue());
        Example example = buildExample(empInfoQuery, tokenUser);
        List<EmpInfoListVO> empInfoListVOList = new ArrayList<>();
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(empInfoDOList)) {
            empInfoDOList.forEach(item -> empInfoListVOList.add(item.to(EmpInfoListVO.class)));
        }
        return empInfoListVOList;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoToFormalRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setEmployType(true);
        empInfoQuery.setFormalType(PROBATION.getValue());
        Example example = buildExample(empInfoQuery, tokenUser);
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        Page<EmpInfoDO> page = empInfoDAO.selectPageByExample(example, empInfoQuery.getPageNo(),
                empInfoQuery.getPageSize());
        if (CollectionUtils.isEmpty(page.getEntities())) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
        return page.to(EmpInfoListVO.class);
    }

    @Override
    public List<EmpInfoListVO> selectEmpInfoToFormalRelationList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setEmployType(true);
        empInfoQuery.setFormalType(PROBATION.getValue());
        Example example = buildExample(empInfoQuery, tokenUser);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return new ArrayList<>();
        }
        return empInfoDOList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class)).collect(Collectors.toList());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoLeaveRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {

        // 查询预离职时间在某个时间段的员工
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        if (empInfoQuery.getLeaveDateStart() != null) {
            empChangesQuery.setPreQuitDateStart(empInfoQuery.getLeaveDateStart());
            empInfoQuery.setLeaveDateStart(null);
        }
        if (empInfoQuery.getLeaveDateEnd() != null) {
            empChangesQuery.setPreQuitDateEnd(empInfoQuery.getLeaveDateEnd());
            empInfoQuery.setLeaveDateEnd(null);
        }
        if (empInfoQuery.getCompanyId() != null) {
            empChangesQuery.setCompanyId(empInfoQuery.getCompanyId());
        }
        Example example = buildExample(empInfoQuery, tokenUser);
        // 高级筛选：标签
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        // 是否只查询审批通过和不需要审批的人员
        if (empInfoQuery.getIsApproPass() != null && empInfoQuery.getIsApproPass()) {
            example.and()
                    .andIn("approvalStatus",
                            ArrayKit.asList(new Integer[]{ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                                    ApprovalStatusEnum.APPRO_DISABLE.getValue()}));
        }
        //查询公司所有自定义字段
        //查询所有自定义字段
        List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList =
                companyAdditionalFieldsService.selectOpenByCompanyId(empInfoQuery.getCompanyId(), tokenUser.getSiteId());
        if (HAS_QUIT.getValue().equals(empInfoQuery.getStatus())) {
            Page<EmpInfoListVO> empInfoListVOPage = pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(),
                    empInfoQuery.getPageSize(), tokenUser.getSiteId());
            //填充员工自定义属性
            customAttributeFill(empInfoListVOPage.getEntities(), companyAdditionalFieldsListVOList);
            // 添加渠道信息
            addChannelInfo(empInfoListVOPage.getEntities(), tokenUser.getSiteId());
            return empInfoListVOPage;
        }
        empChangesQuery.setChangeType(EmpChangeType.LEAVE.getValue());

        // 分页查询员工信息并设置变动记录
        Page<EmpInfoListVO> empInfoListVOPage = selectPageEmpInfoAndSetEmpChanges(empChangesQuery, empInfoQuery, example, tokenUser.getSiteId());
        //填充员工自定义属性
        customAttributeFill(empInfoListVOPage.getEntities(), companyAdditionalFieldsListVOList);
        // 添加渠道信息
        addChannelInfo(empInfoListVOPage.getEntities(), tokenUser.getSiteId());
        return empInfoListVOPage;
    }

    /**
     * 设置渠道信息
     */
    private void addChannelInfo(List<EmpInfoListVO> empInfoListVOS, String siteId) {
        List<String> channelIds = empInfoListVOS.parallelStream().map(EmpInfoListVO::getChannelId).collect(Collectors.toList());
        List<ChannelVO> channelVOS = channelService.selectByIds(channelIds, siteId);
        Map<String, ChannelVO> idChannelMap = channelVOS.parallelStream().collect(Collectors.toMap(ChannelVO::getId, v -> v));
        for (EmpInfoListVO empInfoListVO : empInfoListVOS) {
            String channelId = empInfoListVO.getChannelId();
            if (StrKit.isNotEmpty(channelId)) {
                ChannelVO channelVO = idChannelMap.get(channelId);
                if (channelVO != null) {
                    empInfoListVO.setChannelName(channelVO.getName());
                }
            }
        }
    }

    @Override
    public EmpInfoPasteVO selectEmpInfoLeaveRelationByIdCards(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        for (String idCard : idCards) {
            Example example = new Example(EmpInfoDO.class);
            example.and()
                    .andIn("approvalStatus", ArrayKit.asList(new Integer[]{4, 5}))
                    .andEqualTo("status", 3)
                    .andEqualTo("idCard", idCard)
                    .andEqualTo("companyId", companyId)
                    .andEqualTo("valid", true);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
            if (!CollectionUtils.isEmpty(empInfoDOList)) {
                EmpInfoDO empInfoDO = empInfoDOList.get(0);
                if (empInfoVOList.removeIf(empInfoVO -> empInfoVO.getId().equals(empInfoDO.getId()))) {
                    idCardList.add(idCard);
                }
                empInfoVOList.add(empInfoDO.to(EmpInfoVO.class));
            } else {
                idCardList.add(idCard);
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public List<EmpInfoListVO> selectEmpInfoLeaveRelationList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        // 查询预转正时间在某个时间段的员工
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        if (empInfoQuery.getLeaveDateStart() != null) {
            empChangesQuery.setPreQuitDateStart(empInfoQuery.getLeaveDateStart());
            empInfoQuery.setLeaveDateStart(null);
        }
        if (empInfoQuery.getLeaveDateEnd() != null) {
            empChangesQuery.setPreQuitDateEnd(empInfoQuery.getLeaveDateEnd());
            empInfoQuery.setLeaveDateEnd(null);
        }

        Example example = buildExample(empInfoQuery, tokenUser);

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and().andEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        // 根据离职时间查询
        empChangesQuery.setChangeType(EmpChangeType.LEAVE.getValue());
        // 查询变动记录，并设置员工查询的id
        List<EmpChangesListVO> empChangesList = selectEmpChangesAndSetEmpQueryExample(empChangesQuery, example, tokenUser.getSiteId());
        // 查询员工信息，并设置上员工的变动记录
        return selectEmpInfoAndAddEmpChangesInfo(empChangesList, example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoTransferRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setChangeStatus(2);
        Example example = buildExample(empInfoQuery, tokenUser);
        if (Boolean.TRUE.equals(empInfoQuery.getIsApproPass())) {
            example.and().andIn("approvalStatus",
                    Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                            ApprovalStatusEnum.APPRO_DISABLE.getValue()));
        }
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }

        // 查询调岗时间在某个时间段的员工
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        empChangesQuery.setCompanyId(empInfoQuery.getCompanyId());
        if (empInfoQuery.getTransferDateStart() != null) {
            empChangesQuery.setAdjustmentDateStart(empInfoQuery.getTransferDateStart());
        }
        if (empInfoQuery.getTransferDateEnd() != null) {
            empChangesQuery.setAdjustmentDateEnd(empInfoQuery.getTransferDateEnd());
        }
        // 根据调岗时间查询
        empChangesQuery.setChangeType(EmpChangeType.TRANSFER__POSITION.getValue());
        // 分页查询员工信息并设置变动记录
        return selectPageEmpInfoAndSetEmpChanges(empChangesQuery, empInfoQuery, example, tokenUser.getSiteId());
    }

    /**
     * 分页查询员工信息并设置变动记录
     */
    private Page<EmpInfoListVO> selectPageEmpInfoAndSetEmpChanges(EmpChangesQuery empChangesQuery,
                                                                  EmpInfoQuery empInfoQuery,
                                                                  Example example, String siteId) {
        // 查询变动记录，并设置员工查询的id
        List<EmpChangesListVO> empChangesList = selectEmpChangesAndSetEmpQueryExample(empChangesQuery, example, siteId);
        // 没有调岗记录
        if (CollectionUtils.isEmpty(empChangesList)) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
        Page<EmpInfoListVO> page = pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(), empInfoQuery.getPageSize(), siteId);
        //添加部门和岗位
        addDepAndPositionToEmpList(page.getEntities(), empInfoQuery.getCompanyId(), siteId);
        // 添加员工变动记录
        addEmpChangesInfo(empChangesList, page.getEntities());
        // 添加渠道信息
        addChannelInfo(page.getEntities(), siteId);
        return page;
    }

    /**
     * 添加员工变动记录
     */
    private void addEmpChangesInfo(List<EmpChangesListVO> empChangesList, List<EmpInfoListVO> empInfoListVOList) {
        if (CollectionUtils.isEmpty(empInfoListVOList) || CollectionUtils.isEmpty(empChangesList)) {
            return;
        }
        // 按员工id分组,并保留顺序
        Map<String, List<EmpChangesListVO>> empIdChangesMap = empChangesList.stream()
                .collect(Collectors.groupingBy(EmpChangesListVO::getEmpId,
                        LinkedHashMap::new, Collectors.toList()));
        for (EmpInfoListVO empInfoListVO : empInfoListVOList) {
            // 当前员工的变动记录
            List<EmpChangesListVO> empChangesListVOList = empIdChangesMap.get(empInfoListVO.getId());
            if (!CollectionUtils.isEmpty(empChangesListVOList)) {
                empInfoListVO.setEmpChangesListVO(empChangesListVOList.get(0));
                //添加岗位部门名称（原现）
                addDepNameAndPositionName(empInfoListVO);
            }
        }
    }

    private void addDepNameAndPositionName(EmpInfoListVO empInfoListVO) {
        //过去的部门
        if (empInfoListVO.getEmpChangesListVO().getPreDep() != null) {
            DepInfoVO preDepInfoVO =
                    depInfoService.selectByIdWhetherDel(
                            empInfoListVO.getEmpChangesListVO().getPreDep(), empInfoListVO.getSiteId());
            if (preDepInfoVO != null) {
                empInfoListVO.getEmpChangesListVO().setPreDepName(preDepInfoVO.getName());
            }
        } else {
            empInfoListVO.getEmpChangesListVO().setPreDepName("暂无");
        }
        //当前部门
        if (empInfoListVO.getEmpChangesListVO().getCurrentDep() != null) {
            DepInfoVO currentDepInfoVO =
                    depInfoService.selectByIdWhetherDel(
                            empInfoListVO.getEmpChangesListVO().getCurrentDep(), empInfoListVO.getSiteId());
            if (currentDepInfoVO != null) {
                empInfoListVO.getEmpChangesListVO().setCurrentDepName(currentDepInfoVO.getName());
            }

        }
        //过去岗位
        if (empInfoListVO.getEmpChangesListVO().getPrePosition() != null) {
            PositionInfoVO prePositionInfoVO =
                    positionInfoService.selectByIdWhetherDel(
                            empInfoListVO.getEmpChangesListVO().getPrePosition(), empInfoListVO.getSiteId());
            if (prePositionInfoVO != null) {
                empInfoListVO.getEmpChangesListVO().setPrePositionName(prePositionInfoVO.getName());
            }
        } else {
            empInfoListVO.getEmpChangesListVO().setPrePositionName("暂无");
        }
        //当前岗位
        if (empInfoListVO.getEmpChangesListVO().getCurrentPosition() != null) {
            PositionInfoVO currentPositionInfoVO =
                    positionInfoService.selectByIdWhetherDel(
                            empInfoListVO.getEmpChangesListVO().getCurrentPosition(), empInfoListVO.getSiteId());
            if (currentPositionInfoVO != null) {
                empInfoListVO.getEmpChangesListVO().setCurrentPositionName(currentPositionInfoVO.getName());
            }
        }
    }

    @Override
    public List<EmpInfoListVO> selectEmpInfoTransferRelationList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        Example example = buildExample(empInfoQuery, tokenUser);

        // 查询调岗时间在某个时间段的员工
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        empChangesQuery.setCompanyId(empInfoQuery.getCompanyId());
        if (empInfoQuery.getTransferDateStart() != null) {
            empChangesQuery.setAdjustmentDateStart(empInfoQuery.getTransferDateStart());
        }
        if (empInfoQuery.getTransferDateEnd() != null) {
            empChangesQuery.setAdjustmentDateEnd(empInfoQuery.getTransferDateEnd());
        }
        // 调岗
        empChangesQuery.setChangeType(EmpChangeType.TRANSFER__POSITION.getValue());
        // 查询变动记录，并设置员工查询的id
        List<EmpChangesListVO> empChangesList = selectEmpChangesAndSetEmpQueryExample(empChangesQuery, example, tokenUser.getSiteId());
        // 查询员工信息，并设置上员工的变动记录
        return selectEmpInfoAndAddEmpChangesInfo(empChangesList, example);
    }

    /**
     * 查询变动记录，并设置员工查询的id
     */
    private List<EmpChangesListVO> selectEmpChangesAndSetEmpQueryExample(EmpChangesQuery empChangesQuery,
                                                                         Example example, String siteId) {
        // 按修改时间倒序
        Order order = new Order("gmtModified", true);
        empChangesQuery.setOrders(Collections.singletonList(order));
        // 初始状态
        empChangesQuery.setChangeStatus(0);
        List<EmpChangesListVO> empChangesList = empChangesService.select(empChangesQuery, siteId);
        // 没有调岗记录
        if (CollectionUtils.isEmpty(empChangesList)) {
            example.and().andEqualTo("id", "-1");
            return new ArrayList<>();
        }
        List<String> empIdList = empChangesList.parallelStream()
                .map(EmpChangesListVO::getEmpId)
                .collect(Collectors.toList());
        example.and().andIn("id", empIdList);
        return empChangesList;
    }

    /**
     * 查询员工信息，并设置上员工的变动记录
     */
    private List<EmpInfoListVO> selectEmpInfoAndAddEmpChangesInfo(List<EmpChangesListVO> empChangesList, Example example) {
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return new ArrayList<>();
        }
        List<EmpInfoListVO> empInfoListVOList = empInfoDOList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class)).collect(Collectors.toList());
        // 添加员工变动记录
        addEmpChangesInfo(empChangesList, empInfoListVOList);
        return empInfoListVOList;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Page<EmpInfoListVO> selectEmpInfoListForLeave(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setEmployType(true);
        Example example = buildExample(empInfoQuery, tokenUser);
        example.and().andNotEqualTo("changeStatus", 2);
        return pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(), empInfoQuery.getPageSize(), tokenUser.getSiteId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpAllInfoVO findEmpInfoRelation(String empInfoId, String siteId) {
        long l1 = System.currentTimeMillis();
        EmpInfoDO empInfoDO = selectDOById(empInfoId, siteId);
        if (Objects.isNull(empInfoDO)) {
            return null;
        }
        // 校验userDO是否存在  不存在 清空员工的userId
        List<UserDO> userDOList = userProviderService.selectUserByIds(Collections.singletonList(empInfoDO.getUserId()));
        if (CollectionUtils.isEmpty(userDOList)) {
            empInfoDO.setUserId(null);
            updateById(empInfoDO, siteId, "system");
        }

        EmpAllInfoVO empAllInfoVO = empInfoDO.to(EmpAllInfoVO.class);

        CompanyDO companyDO = companyService.selectDOById(empAllInfoVO.getCompanyId(), siteId);
        if (Objects.nonNull(companyDO)) {
            empAllInfoVO.setCompanyName(companyDO.getName());
        }
        if (empInfoDO.getHighestEducation() == null) {
            Map<String, String> highestEducation = empEducationService.selectHighestEducationAndDegree(empInfoDO.getId());
            empInfoDO.setHighestEducation(highestEducation.get("education"));
        }

        // 司龄,加入公司时长
        double joinCompanyLength = DateUtils.getJoinCompanyLength(empAllInfoVO.getJoinDate(), empAllInfoVO.getLeaveDate());
        String birthday = empAllInfoVO.getBirthday();
        int age = DateUtils.getYearDiff(DateKit8.parseDateTime(birthday), DateKit.getToday());
        // 加入公司时长
        empAllInfoVO.setJoinCompanyLength(joinCompanyLength);
        empAllInfoVO.setAge(age);
        //更新一下花名册中的年龄
        empInfoDO.setEmpAge(age);
        empInfoDAO.updateByPrimaryKeySelective(empInfoDO);
        // 生日日期型
        empAllInfoVO.setBirthdayStr(birthday);

        long l2 = System.currentTimeMillis();
        log.info("==========查询员工相关信息,耗时{}ms:", (l2 - l1));

        // 人员所属部门名称
        Map<String, String> depMap = listDepNameByEmp(empAllInfoVO.getCompanyId(), empAllInfoVO.getId(), siteId);
        //部门集合
        if (depMap.size() > 0) {
            List<String> depIdList = new ArrayList<>();
            List<String> depNameList = new ArrayList<>();
            depMap.forEach(
                    (key, value) -> {
                        depIdList.add(key);
                        depNameList.add(value);
                    }
            );
            empAllInfoVO.setDepIdList(depIdList);
            empAllInfoVO.setDepName(String.join(",", depNameList));
        }
        //  岗位集合
        Map<String, String> positionMap = listPositionNameByEmp(empAllInfoVO.getCompanyId(), empAllInfoVO.getId(), siteId);

        if (positionMap.size() > 0) {
            List<String> positionIdList = new ArrayList<>();
            List<String> positionNameList = new ArrayList<>();
            positionMap.forEach(
                    (key, value) -> {
                        positionIdList.add(key);
                        positionNameList.add(value);
                    }
            );
            empAllInfoVO.setPositionIdList(positionIdList);
            empAllInfoVO.setPositionName(String.join(",", positionNameList));
        }
        //证件集合
        List<EmpCardDO> empCardList = empCardService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empCardList)) {
            List<EmpCardVO> empCardVoList = empCardList.stream().map(empCard -> empCard.to(EmpCardVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpCardList(empCardVoList);
        }

        //家庭成员集合
        List<EmpFamilyDO> empFamilyList = empFamilyService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empFamilyList)) {
            List<EmpFamilyVO> empFamilyVoList = empFamilyList.stream().map(empFamilyDO -> empFamilyDO.to(EmpFamilyVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpFamilyList(empFamilyVoList);
        }

        //奖惩记录集合
        List<EmpRewardPunishDO> empRewardPunishList = empRewardPunishService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empRewardPunishList)) {
            List<EmpRewardPunishVO> empRewardPunishVoList = empRewardPunishList.stream().map(empRewardPunishDO -> empRewardPunishDO.to(EmpRewardPunishVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpRewardPunishList(empRewardPunishVoList);
        }


        //证书集合
        List<EmpCertificateDO> empCertificateList = empCertificateService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empCertificateList)) {
            List<EmpCertificateVO> empCertificateVoList = empCertificateList.stream().map(empCertificate -> empCertificate.to(EmpCertificateVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpCertificateList(empCertificateVoList);
        }

        //联系人集合
        List<EmpContactsDO> empContactsList = empContactsService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empContactsList)) {
            List<EmpContactsVO> empContactsVoList = empContactsList.stream().map(empContacts -> empContacts.to(EmpContactsVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpContactsList(empContactsVoList);
        }

        //合同集合
        List<EmpContractDO> empContractList = empContractService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empContractList)) {
            List<EmpContractVO> empContractVoList = empContractList.stream().map(empContract -> empContract.to(EmpContractVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpContractList(empContractVoList);
        }

        //教育经历集合
        List<EmpEducationDO> empEducationList = empEducationService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empEducationList)) {
            List<EmpEducationVO> empEducationVoList = empEducationList.stream().map(empEducation -> empEducation.to(EmpEducationVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpEducationList(empEducationVoList);
        }

        //培训记录集合
        List<EmpTrainDO> empTrainList = empTrainService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empTrainList)) {
            List<EmpTrainVO> empTrainVoList = empTrainList.stream().map(empTrain -> empTrain.to(EmpTrainVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpTrainList(empTrainVoList);
        }

        //工作经历集合
        List<EmpWorkDO> empWorkList = empWorkService.listByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empWorkList)) {
            List<EmpWorkVO> empWorkVoList = empWorkList.stream().map(empWork -> empWork.to(EmpWorkVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpWorkList(empWorkVoList);
        }

        //纸质合同
        List<EmpPaperContractDO> empPaperContractList = empPaperContractService.listContractByEmpId(empInfoId, siteId);
        if (!CollectionUtils.isEmpty(empPaperContractList)) {
            List<EmpPaperContractVO> empPaperContractVoList = empPaperContractList.stream().map(contract -> contract.to(EmpPaperContractVO.class))
                    .collect(Collectors.toList());
            empAllInfoVO.setEmpPaperContractList(empPaperContractVoList);
        }

        //额外基本信息
        CompanyNecessaryFieldQuery companyNecessaryFieldQuery = new CompanyNecessaryFieldQuery();
        companyNecessaryFieldQuery.setCompanyId(empInfoDO.getCompanyId());
        companyNecessaryFieldQuery.setEmpInfoId(empInfoId);
        TokenUser tokenUser = new TokenUser();
        tokenUser.setUserId(empInfoDO.getCreateUserId());
        tokenUser.setSiteId(siteId);
        CompanyFieldAndValueListVO companyFieldAndValueListVO =
                companyNecessaryFieldService.listAllForApp(companyNecessaryFieldQuery, tokenUser);
        empAllInfoVO.setCompanyAdditionalFieldsListBasicVOList(
                companyFieldAndValueListVO.getCompanyAdditionalFieldsBasicVOList());
        //额外联系信息
        empAllInfoVO.setCompanyAdditionalFieldsListContactVOList(
                companyFieldAndValueListVO.getCompanyAdditionalFieldsContactVOList());
        //额外附件信息
        empAllInfoVO.setCompanyAdditionalFieldsListAttachmentVOList(
                companyFieldAndValueListVO.getCompanyAdditionalFieldsAttachmentVOList());
        //员工档案资料
        empAllInfoVO.setCompanyAdditionalFieldsListArchiveVOList(
                companyFieldAndValueListVO.getCompanyAdditionalFieldsArchiveVOList());
        //员工离职资料
        empAllInfoVO.setCompanyAdditionalFieldsListLeaveOfficeVOList(
                companyFieldAndValueListVO.getCompanyAdditionalFieldsLeaveOfficeVOList());


        return empAllInfoVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpAllInfoVO findEmpInfoRelationAsync(String empInfoId, String siteId) {
        long l1 = System.currentTimeMillis();
        EmpInfoDO empInfoDO = selectDOById(empInfoId, siteId);
        if (Objects.isNull(empInfoDO)) {
            return null;
        }
        // 校验userDO是否存在  不存在 清空员工的userId
        List<UserDO> userDOList = userProviderService.selectUserByIds(Collections.singletonList(empInfoDO.getUserId()));
        if (CollectionUtils.isEmpty(userDOList)) {
            empInfoDO.setUserId(null);
            updateById(empInfoDO, siteId, "system");
        }

        EmpAllInfoVO empAllInfoVO = empInfoDO.to(EmpAllInfoVO.class);

        CompanyDO companyDO = companyService.selectDOById(empAllInfoVO.getCompanyId(), siteId);
        if (Objects.nonNull(companyDO)) {
            empAllInfoVO.setCompanyName(companyDO.getName());
        }
        if (empInfoDO.getHighestEducation() == null) {
            Map<String, String> highestEducation = empEducationService.selectHighestEducationAndDegree(empInfoDO.getId());
            empInfoDO.setHighestEducation(highestEducation.get("education"));
        }

        // 司龄,加入公司时长
        double joinCompanyLength = DateUtils.getJoinCompanyLength(empAllInfoVO.getJoinDate(), empAllInfoVO.getLeaveDate());
        String birthday = empAllInfoVO.getBirthday();
        int age = DateUtils.getYearDiff(DateKit8.parseDateTime(birthday), DateKit.getToday());
        // 加入公司时长
        empAllInfoVO.setJoinCompanyLength(joinCompanyLength);
        empAllInfoVO.setAge(age);
        //更新一下花名册中的年龄
        empInfoDO.setEmpAge(age);
        empInfoDAO.updateByPrimaryKeySelective(empInfoDO);
        // 生日日期型
        empAllInfoVO.setBirthdayStr(birthday);

        long l2 = System.currentTimeMillis();
        log.info("==========查询员工相关信息,耗时{}ms:", (l2 - l1));

        try {
            //部门集合
            Future<EmpAllInfoVO> depVo = asyncEmpInfoDetailService.
                    listDepNameByEmp(empAllInfoVO.getCompanyId(), empAllInfoVO.getId(), siteId);

            //岗位集合
            Future<EmpAllInfoVO> positionVo = asyncEmpInfoDetailService.
                    listPositionNameByEmp(empAllInfoVO.getCompanyId(), empAllInfoVO.getId(), siteId);

            //证件集合
            Future<EmpAllInfoVO> cardVo = asyncEmpInfoDetailService.
                    cardListByEmpId(empInfoId, siteId);

            //家庭成员集合
            Future<EmpAllInfoVO> familyVo = asyncEmpInfoDetailService.
                    familyListByEmpId(empInfoId, siteId);

            //奖惩记录集合
            Future<EmpAllInfoVO> rewardPunishVo = asyncEmpInfoDetailService.
                    rewardPunishListByEmpId(empInfoId, siteId);

            //证书集合
            Future<EmpAllInfoVO> certificateVo = asyncEmpInfoDetailService.
                    certificateListByEmpId(empInfoId, siteId);

            //联系人集合
            Future<EmpAllInfoVO> contactVo = asyncEmpInfoDetailService.
                    contactListByEmpId(empInfoId, siteId);

            //合同集合
            Future<EmpAllInfoVO> contractVo = asyncEmpInfoDetailService.
                    contractListByEmpId(empInfoId, siteId);

            //教育经历集合
            Future<EmpAllInfoVO> educationVo = asyncEmpInfoDetailService.
                    educationListByEmpId(empInfoId, siteId);

            //培训记录集合
            Future<EmpAllInfoVO> trainVo = asyncEmpInfoDetailService.
                    trainListByEmpId(empInfoId, siteId);

            //工作经历集合
            Future<EmpAllInfoVO> empWorkVo = asyncEmpInfoDetailService.
                    empWorkListByEmpId(empInfoId, siteId);

            //纸质合同
            Future<EmpAllInfoVO> paperContractVo = asyncEmpInfoDetailService.
                    paperContractListByEmpId(empInfoId, siteId);

            //额外基本信息
            Future<EmpAllInfoVO> additionVo = asyncEmpInfoDetailService.
                    additionListByEmpId(empInfoDO);

            EmpAllInfoVO dep = depVo.get();
            if (dep != null) {
                empAllInfoVO.setDepIdList(dep.getDepIdList());
                empAllInfoVO.setDepName(dep.getDepName());
            }

            EmpAllInfoVO position = positionVo.get();
            if (position != null) {
                empAllInfoVO.setPositionInfoList(position.getPositionInfoList());
                empAllInfoVO.setPositionName(position.getPositionName());
            }

            EmpAllInfoVO card = cardVo.get();
            if (card != null) {
                empAllInfoVO.setEmpCardList(card.getEmpCardList());
            }

            EmpAllInfoVO family = familyVo.get();
            if (family != null) {
                empAllInfoVO.setEmpFamilyList(family.getEmpFamilyList());
            }

            EmpAllInfoVO rewardPunish = rewardPunishVo.get();
            if (rewardPunish != null) {
                empAllInfoVO.setEmpRewardPunishList(rewardPunish.getEmpRewardPunishList());
            }

            EmpAllInfoVO certificate = certificateVo.get();
            if (certificate != null) {
                empAllInfoVO.setEmpCertificateList(certificate.getEmpCertificateList());
            }

            EmpAllInfoVO contacts = contactVo.get();
            if (contacts != null) {
                empAllInfoVO.setEmpContactsList(contacts.getEmpContactsList());
            }

            EmpAllInfoVO contract = contractVo.get();
            if (contract != null) {
                empAllInfoVO.setEmpContractList(contract.getEmpContractList());
            }

            EmpAllInfoVO education = educationVo.get();
            if (education != null) {
                empAllInfoVO.setEmpEducationList(education.getEmpEducationList());
            }

            EmpAllInfoVO train = trainVo.get();
            if (train != null) {
                empAllInfoVO.setEmpTrainList(train.getEmpTrainList());
            }

            EmpAllInfoVO work = empWorkVo.get();
            if (work != null) {
                empAllInfoVO.setEmpWorkList(work.getEmpWorkList());
            }

            EmpAllInfoVO paperContract = paperContractVo.get();
            if (paperContract != null) {
                empAllInfoVO.setEmpPaperContractList(paperContract.getEmpPaperContractList());
            }

            EmpAllInfoVO addition = additionVo.get();
            if (addition != null) {
                //额外联系信息
                empAllInfoVO.setCompanyAdditionalFieldsListContactVOList(
                        addition.getCompanyAdditionalFieldsListContactVOList());
                //额外附件信息
                empAllInfoVO.setCompanyAdditionalFieldsListAttachmentVOList(
                        addition.getCompanyAdditionalFieldsListAttachmentVOList());
                //员工档案资料
                empAllInfoVO.setCompanyAdditionalFieldsListArchiveVOList(
                        addition.getCompanyAdditionalFieldsListArchiveVOList());
                //员工离职资料
                empAllInfoVO.setCompanyAdditionalFieldsListLeaveOfficeVOList(
                        addition.getCompanyAdditionalFieldsListLeaveOfficeVOList());
            }
        } catch (Exception e) {
            log.error("异步拼装花名册详情：", e);
        }

        return empAllInfoVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpAllInfoVO findEmpInfoRelationByUserId(String userId, TokenUser tokenUser) {
        EmpInfoQuery empInfoQuery = new EmpInfoQuery();
        empInfoQuery.setUserId(userId);

        List<EmpInfoDO> empInfoList = listByUserId(userId, tokenUser.getSiteId());

        if (!CollectionUtils.isEmpty(empInfoList)) {
            EmpInfoDO empInfoDO = empInfoList.get(0);
            EmpAllInfoVO empAllInfoVO = findEmpInfoRelation(empInfoDO.getId(), tokenUser.getSiteId());
            if (StringUtils.isNotBlank(empInfoDO.getUnionId())) {
                ThirdInfoDO thirdInfoDO = thirdInfoService.selectByUnionId(empInfoDO.getUnionId());
                if (Objects.nonNull(thirdInfoDO)) {
                    empAllInfoVO.setHeadImgUrl(thirdInfoDO.getHeadImgUrl());
                    empAllInfoVO.setNickName(thirdInfoDO.getNickName());
                }
            }
            return empAllInfoVO;
        }
        return null;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpAllInfoVO findEmpInfoRelationByUserId2(String userId, TokenUser tokenUser) {
        EmpInfoQuery empInfoQuery = new EmpInfoQuery();
        empInfoQuery.setUserId(userId);

        List<EmpInfoDO> empInfoList = listByUserId2(userId, tokenUser.getSiteId());

        if (!CollectionUtils.isEmpty(empInfoList)) {
            EmpInfoDO empInfoDO = empInfoList.get(0);
            EmpAllInfoVO empAllInfoVO = findEmpInfoRelation(empInfoDO.getId(), tokenUser.getSiteId());
            if (StringUtils.isNotBlank(empInfoDO.getUnionId())) {
                ThirdInfoDO thirdInfoDO = thirdInfoService.selectByUnionId(empInfoDO.getUnionId());
                if (Objects.nonNull(thirdInfoDO)) {
                    empAllInfoVO.setHeadImgUrl(thirdInfoDO.getHeadImgUrl());
                    empAllInfoVO.setNickName(thirdInfoDO.getNickName());
                }
            }
            // 查询该员工的微工卡授权状态
            String openId = userProviderService.selectOpenIdByUserId(userId, tokenUser);
            if (StrKit.isNotEmpty(openId)) {
                empAllInfoVO.setVxWgkUserAuthResultVO(transferAccountInfoService
                        .selectUserAuthStatus(openId, tokenUser.getSiteId()));
            }
            return empAllInfoVO;
        }
        return null;
    }

    @Override
    public List<EmpInfoDO> listByUserId(String userId, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("userId", userId)
                .andEqualTo("valid", true)
                .andIn("status", Arrays.asList(HAS_ENTRY.getValue(), EmpInfoStatus.WAIT_QUIT.getValue()))
                .andEqualTo("siteId", siteId);
        example.orderBy("gmtCreate").asc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listByUserId2(String userId, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("userId", userId)
                .andEqualTo("valid", true)
                // 2021-11-26 待入职员工也可进入小程序，该筛选条件无用，暂时取消
                //.andIn("status", Arrays.asList(HAS_ENTRY.getValue(), EmpInfoStatus.WAIT_QUIT.getValue(), EmpInfoStatus.HAS_QUIT.getValue()))
                .andEqualTo("siteId", siteId);
        example.setOrderByClause("FIELD(status,'2','3','1','4'), gmt_create desc");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listByUserIdNotSiteId(String userId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("userId", userId)
                .andEqualTo("valid", true);
        // 2021-11-26 待入职员工也可进入小程序，该筛选条件无用，暂时取消
        //.andIn("status", Arrays.asList(HAS_ENTRY.getValue(), EmpInfoStatus.WAIT_QUIT.getValue(), EmpInfoStatus.HAS_QUIT.getValue()));
        example.orderBy("gmtCreate").desc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listByUserIdList(List<String> userIdList, String siteId) {
        if (CollectionUtils.isEmpty(userIdList)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("userId", userIdList)
                .andEqualTo("valid", true)
                .andIn("status", Arrays.asList(HAS_ENTRY.getValue(), EmpInfoStatus.WAIT_QUIT.getValue()))
                .andEqualTo("siteId", siteId);
        example.orderBy("gmtCreate").asc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoPositionVO findEmpInfoPosition(String companyId, String empInfoId, String siteId) {
        return empInfoDAO.findEmpInfoPosition(companyId, empInfoId, siteId);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public List<EmpInfoDO> listWithSalary(EmpInfoDO empInfoDO, String siteId) {
        return empInfoDAO.listWithSalary(empInfoDO, siteId);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void deleteByCompanyId(String companyId, TokenUser tokenUser) {
        // 逻辑删除
        List<EmpInfoDO> list = listByCompanyId(companyId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(list)) {
            return;
        }
        String[] ids = list.stream()
                .map(BaseDO::getId).toArray(String[]::new);
        deleteByIds(tokenUser, ids);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoVO saveEmpInfoPre(EmpInfoAddDTO empInfoAddDTO, TokenUser tokenUser) {
        EmpInfoVO empInfoVO = save(empInfoAddDTO, tokenUser);

        HrLogKit.logForSave("新增待入职员工,员工姓名:" + empInfoVO.getName(),
                "saveEmpInfoPre", empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);
        return empInfoVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoVO saveEmpAllInfo(EmpAllInfoAddDTO empAllInfoAddDTO, TokenUser tokenUser) {
        //预登记转待入职，之前的empInfo信息和operationEmp表信息需要删除
        deleteOperation(empAllInfoAddDTO, tokenUser);
        // 校验用工单位身份证唯一
        checkIdCard(empAllInfoAddDTO.getIdCard(), empAllInfoAddDTO.getCompanyId(), tokenUser);
        // 校验预登记
        addCheckInPeople(empAllInfoAddDTO, tokenUser);
        // 是否需要新增预登记人员
        updataCheckInPeople(empAllInfoAddDTO.getName(), empAllInfoAddDTO.getIdCard(), empAllInfoAddDTO.getChannelId(),
                empAllInfoAddDTO.getPhone(), tokenUser, empAllInfoAddDTO.getStatus(), empAllInfoAddDTO.getCheckInId());

        EmpInfoAddDTO empInfoAdd = empAllInfoAddDTO.to(EmpInfoAddDTO.class);
        // 处理传过来的身份证照片
        processAnnexIdCard(empAllInfoAddDTO, empInfoAdd);

        EmpInfoVO empInfoVO = save(empInfoAdd, tokenUser);
        EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO = empAllInfoAddDTO.to(EmpInfoAndRuleAddDTO.class);
        // 员工设置字段赋值，家庭成员+紧急联系人
        saveTemplateFieldData(empInfoVO.getId(), empInfoAndRuleAddDTO, tokenUser);
        // 添加动态码信息
        addByCode(empAllInfoAddDTO.getCode(), empInfoVO);
        // 添加自定义字段值
        saveAdditionalField(empAllInfoAddDTO.getAddEmpFieldList(), empAllInfoAddDTO.getCompanyId(), empInfoVO.getId(), tokenUser);
        // 待入职发起审批
        addApprove(empAllInfoAddDTO, empInfoVO, tokenUser);
        EmpAllInfoDTO empAllInfoDTO = empAllInfoAddDTO.to(EmpAllInfoDTO.class);
        // 在职员工需要将 要入职的部门和要入职的岗位转换成 部门和岗位
        if (empAllInfoAddDTO.getStatus() != null && empAllInfoAddDTO.getStatus() == 2) {
            // 部门修改
            if (empAllInfoAddDTO.getPreJoinDep() != null) {
                if (StringUtils.isNotBlank(empAllInfoAddDTO.getPreJoinDep())) {
                    String[] split = empAllInfoAddDTO.getPreJoinDep().split(",");
                    List<EmpDepAddDTO> empDepAddDTOList = new ArrayList<>();
                    for (String preJoinDep : split) {
                        EmpDepAddDTO empDepAddDTO = new EmpDepAddDTO();
                        empDepAddDTO.setEmpId(empInfoVO.getId());
                        empDepAddDTO.setCompanyId(empAllInfoAddDTO.getCompanyId());
                        empDepAddDTO.setDepId(preJoinDep);
                        empDepAddDTOList.add(empDepAddDTO);
                    }
                    empDepService.batchSave(empDepAddDTOList, tokenUser);
                }
            }
            // 岗位修改
            if (empAllInfoAddDTO.getPreJoinPosition() != null) {
                if (StringUtils.isNotBlank(empAllInfoAddDTO.getPreJoinPosition())) {
                    String[] split = empAllInfoAddDTO.getPreJoinPosition().split(",");
                    List<EmpPositionAddDTO> empPositionAddDTOList = new ArrayList<>();
                    for (String preJoinPosition : split) {
                        EmpPositionAddDTO empPositionAddDTO = new EmpPositionAddDTO();
                        empPositionAddDTO.setEmpId(empInfoVO.getId());
                        empPositionAddDTO.setCompanyId(empAllInfoAddDTO.getCompanyId());
                        empPositionAddDTO.setPositionId(preJoinPosition);
                        empPositionAddDTOList.add(empPositionAddDTO);
                    }
                    empPositionService.batchSave(empPositionAddDTOList, tokenUser);
                }
            }
        }

        // 发布关联信息
        publishEmpRelation(empAllInfoDTO, empInfoVO, tokenUser);
        String userId = null;
        // 开通用户
        if (StringUtils.isEmpty(empInfoVO.getUserId())) {
            UserVO userVO = userProviderService.registerAccount(empInfoVO.getName(), empInfoVO.getPhone(),
                    tokenUser, empInfoVO.getCompanyId());
            userId = userVO.getId();
        }
        // 实名认证
        verified(empInfoVO.getId(), userId, empInfoVO.getName(), empInfoVO.getIdCard(), empAllInfoAddDTO.getIdCardFront(),
                empAllInfoAddDTO.getIdCardBack(), tokenUser);
        String userName;
        if (null != tokenUser.getUserName()) {
            userName = tokenUser.getUserName();
        } else {
            userName = "扫码入职";
        }
        String desc = PersonalEventExample.INSERT_INTO_ADMIN + userName + PersonalEventExample.INSERT_INTO_SYS;
        personalEventService.autoSave(empInfoVO, tokenUser, desc, PersonalEventEnum.ADD.getValue(), PersonalEventEnum.ADD.getDesc());//添加花名册
        HrLogKit.logForSave("由管理员" + userName + "完善入职员工信息,员工姓名:" + empInfoVO.getName(),
                "saveEmpAllInfo", empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);

        //预登记转待入职手机号同步到预登记
        if (!StringUtils.isEmpty(empAllInfoAddDTO.getCheckInId()) && !StringUtils.isEmpty(empAllInfoAddDTO.getPhone())) {
            CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
            checkInPeopleUpdateDTO.setId(empAllInfoAddDTO.getCheckInId());
            checkInPeopleUpdateDTO.setPhone(empAllInfoAddDTO.getPhone());
            checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
        }
        // 生成今日新增内容
        saveOpreation(empAllInfoAddDTO, tokenUser, empInfoVO);
        // 初始化员工社保相关信息
        empSocRelatedService.initRelatedByEmpId(empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = new ArrayList<>();
        list.add(empInfoVO.getId());
        empCompleteInfo(list, tokenUser);

        return empInfoVO;
    }

    /**
     * 处理传过来的身份证照片
     */
    private void processAnnexIdCard(EmpAllInfoAddDTO empAllInfoAddDTO, EmpInfoAddDTO empInfoAdd) {
        // 处理身份证图片
        List<String> annexIdCardList = ArrayKit.split(empAllInfoAddDTO.getAnnexIdCard());
        if (CollectionUtils.isEmpty(annexIdCardList)) {
            annexIdCardList = new ArrayList<>();
        }
        annexIdCardList.add(empAllInfoAddDTO.getIdCardBack());
        annexIdCardList.add(empAllInfoAddDTO.getIdCardFront());
        // 去重,非空
        String annexIdCards = annexIdCardList.stream()
                .distinct()
                .filter(StrKit::isNotEmpty)
                .collect(Collectors.joining(","));
        empInfoAdd.setAnnexIdCard(annexIdCards);
    }

    /**
     * 预登记转待入职，之前的empInfo信息和operationEmp表信息需要删除
     */
    private void deleteOperation(EmpAllInfoAddDTO empAllInfoAddDTO, TokenUser tokenUser) {
        if (!StringUtils.isEmpty(empAllInfoAddDTO.getCheckInId())) {
            CheckInPeopleVO checkInPeopleVO = checkInPeopleService.selectById(empAllInfoAddDTO.getCheckInId(), tokenUser.getSiteId());
            if (checkInPeopleVO == null) {
                return;
            }
            if (!StringUtils.isEmpty(checkInPeopleVO.getPhone())) {
                EmpInfoQuery empInfoQuery = new EmpInfoQuery();
                empInfoQuery.setPhone(checkInPeopleVO.getPhone());

                List<EmpInfoListVO> select = select(empInfoQuery, tokenUser);
                for (EmpInfoListVO empInfoListVO : select) {
                    OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
                    operationEmpRecordQuery.setEmpId(empInfoListVO.getId());
                    List<OperationEmpRecordListVO> select1 = operationEmpRecordService.select(operationEmpRecordQuery, tokenUser.getSiteId());
                    for (OperationEmpRecordListVO operationEmpRecordListVO : select1) {
                        operationEmpRecordService.deleteByIds(tokenUser, operationEmpRecordListVO.getId());
                    }
                }
                empInfoDAO.deleteEmpByPhone(checkInPeopleVO.getPhone(), tokenUser.getSiteId());
            }
        }
    }

    /**
     * 校验指定用工单位身份证是否存在,所有员工状态
     */
    public void checkIdCard(String idCard, String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("idCard", idCard)
                .andEqualTo("companyId", companyId);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(empInfoDOList)) {
            throw new ParamException("当前用工单位身份证【" + idCard + "】重复");
        }
    }

    /**
     * 员工实名认证
     *
     * @param empId       员工id
     * @param userId      用户id
     * @param name        姓名
     * @param idCard      身份证
     * @param idCardFront 身份证国徽面
     * @param idCardBack  身份证人像面
     */
    public void verified(String empId, String userId, String name, String idCard, String idCardFront,
                         String idCardBack, TokenUser tokenUser) {
        // 正反面都有才进行实名认证
        if (StrKit.isEmpty(idCardFront) || StrKit.isEmpty(idCardBack)) {
            return;
        }
        // userId为空
        if (StrKit.isEmpty(userId)) {
            return;
        }
        // 可能存在实名认证过的user信息，导致直接识别为已实名认证
        EmpInfoVO empInfoVO = selectById(empId, tokenUser.getSiteId());
        if (empInfoVO.getVerified()) {
            return;
        }
        NameVerifiedAddDTO nameVerifiedAddDTO = new NameVerifiedAddDTO();
        nameVerifiedAddDTO.setEmpInfoId(empId);
        nameVerifiedAddDTO.setName(name);
        nameVerifiedAddDTO.setIdCard(idCard);
        // 人像面
        nameVerifiedAddDTO.setPositiveUrl(idCardBack);
        nameVerifiedAddDTO.setReverseUrl(idCardFront);
        nameVerifiedService.save(nameVerifiedAddDTO, userId, tokenUser);
    }

    /**
     * 生成今日新增内容
     */
    private void saveOpreation(EmpAllInfoAddDTO empAllInfoAddDTO, TokenUser tokenUser, EmpInfoVO empInfoVO) {
        // 员工端小程序deviceType
        List<DictItemDO> empDictItem = adminProviderService.selectByDictCode("1217");
        List<String> empDeviceType = empDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        // 管理端小程序deviceType
        List<DictItemDO> adminDictItem = adminProviderService.selectByDictCode("1218");
        List<String> adminDeviceType = adminDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        // PC端deviceType
        List<DictItemDO> pcDictItem = adminProviderService.selectByDictCode("1219");
        List<String> pcDeviceType = pcDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        String status = empInfoVO.getStatus() == 1 ? "待入职" : "入职";
        try {
            if (empInfoVO != null) {
                HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                String deviceType = request.getHeader("devicetype");
                OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
                operationEmpRecordAddDTO.setQueryType(2);
                operationEmpRecordAddDTO.setUserId(empInfoVO.getUserId());
                operationEmpRecordAddDTO.setEmpId(empInfoVO.getId());
                operationEmpRecordAddDTO.setCompanyId(empInfoVO.getCompanyId());
                if (pcDeviceType.contains(deviceType)) {
                    operationEmpRecordAddDTO.setSourceTypeInfo("PC" + status);
                    operationEmpRecordAddDTO.setEmpStatus(2);
                    operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                    operationEmpRecordAddDTO.setSourceType(1);


                    if (!StringUtils.isEmpty(empAllInfoAddDTO.getCheckInId())) {
                        operationEmpRecordAddDTO.setCheckInId(empAllInfoAddDTO.getCheckInId());
                        //预登记转待入职
                        OperationEmpRecordAddDTO operationEmpRecordAddDTO1 = new OperationEmpRecordAddDTO();
                        operationEmpRecordAddDTO1.setCompanyId(empAllInfoAddDTO.getCompanyId());
                        operationEmpRecordAddDTO1.setQueryType(2);
                        operationEmpRecordAddDTO1.setInputUserId(tokenUser.getUserId());
                        operationEmpRecordAddDTO1.setUserId(empInfoVO.getUserId());
                        operationEmpRecordAddDTO1.setEmpId(empInfoVO.getId());
                        operationEmpRecordAddDTO1.setCheckInId(empAllInfoAddDTO.getCheckInId());
                        operationEmpRecordAddDTO1.setEmpStatus(2);
                        operationEmpRecordAddDTO1.setSourceType(1);
                        operationEmpRecordAddDTO1.setSourceTypeInfo("预登记转" + status);
                        operationEmpRecordAddDTO1.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpAllInfo");
                        operationEmpRecordService.save(operationEmpRecordAddDTO1, tokenUser);
                        //预登记状态修改
                        CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                        checkInPeopleUpdateDTO.setId(empAllInfoAddDTO.getCheckInId());
                        if (empInfoVO.getStatus() == 1) {
                            checkInPeopleUpdateDTO.setStatus(6);
                        } else {
                            checkInPeopleUpdateDTO.setStatus(4);
                        }
                        checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);

                    }
                } else if (empDeviceType.contains(deviceType)) {
                    if (empInfoVO.getStatus() == 1) {
                        operationEmpRecordAddDTO.setInputUserId(empAllInfoAddDTO.getOperationUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序待入职");
                    } else if (empInfoVO.getStatus() == 2) {
                        operationEmpRecordAddDTO.setInputUserId(empAllInfoAddDTO.getOperationUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序入职");
                    }
                } else if (adminDeviceType.contains(deviceType)) {
                    if (empInfoVO.getStatus() == 1) {
                        operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序管理端转待入职");
                    } else if (empInfoVO.getStatus() == 2) {
                        operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序管理端转入职");
                    }
                }
                operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpAllInfo");
                operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
            }
        } catch (Exception e) {
            log.error("员工记录异常");
        }
    }

    /**
     * 校验审批流程id,如果存在审批流程默认用第一个
     */
    private void checkAppro(EmpAllInfoAddDTO empAllInfoAddDTO, TokenUser tokenUser) {
        String flowId = empAllInfoAddDTO.getFlowId();
        if (StrKit.isEmpty(flowId)) {
            List<ApproFlowListVO> approFlowListVOList = approProviderService.selectByCompanyId(empAllInfoAddDTO.getCompanyId(),
                    ApproType.ON_JOB.getValue(), tokenUser.getSiteId());

            for (ApproFlowListVO approFlowListVO : approFlowListVOList) {
                if (Boolean.TRUE.equals(approFlowListVO.getInUse())) {
                    empAllInfoAddDTO.setFlowId(approFlowListVO.getId());
                    break;
                }
            }
        }
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpInfoVO saveEmpInfoAndRule(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        // 校验预登记
        addCheckInPeople(empInfoAndRuleAddDTO, tokenUser);
        // 是否需要新增规则
        addRule(empInfoAndRuleAddDTO, tokenUser);

        // 是否需要新增预登记人员
        updataCheckInPeople(empInfoAndRuleAddDTO.getName(), empInfoAndRuleAddDTO.getIdCard(),
                empInfoAndRuleAddDTO.getChannelId(), empInfoAndRuleAddDTO.getPhone(), tokenUser, empInfoAndRuleAddDTO.getStatus(), empInfoAndRuleAddDTO.getCheckInId());

        //预登记转入职或待入职，之前的empInfo信息和operationEmp表信息需要删除
        if (!StringUtils.isEmpty(empInfoAndRuleAddDTO.getCheckInId())) {
            CheckInPeopleVO checkInPeopleVO = checkInPeopleService.selectById(empInfoAndRuleAddDTO.getCheckInId(), tokenUser.getSiteId());
            if (!StringUtils.isEmpty(checkInPeopleVO.getPhone())) {
                EmpInfoQuery empInfoQuery = new EmpInfoQuery();
                empInfoQuery.setPhone(checkInPeopleVO.getPhone());

                List<EmpInfoListVO> select = select(empInfoQuery, tokenUser);
                for (EmpInfoListVO empInfoListVO : select) {
                    OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
                    operationEmpRecordQuery.setEmpId(empInfoListVO.getId());
                    List<OperationEmpRecordListVO> select1 = operationEmpRecordService.select(operationEmpRecordQuery, tokenUser.getSiteId());
                    for (OperationEmpRecordListVO operationEmpRecordListVO : select1) {
                        operationEmpRecordService.deleteByIds(tokenUser, operationEmpRecordListVO.getId());
                    }
                }
                empInfoDAO.deleteEmpByPhone(checkInPeopleVO.getPhone(), tokenUser.getSiteId());
            }
        }

        EmpInfoAddDTO empInfoAdd = empInfoAndRuleAddDTO.to(EmpInfoAddDTO.class);
        EmpInfoVO empInfoVO = save(empInfoAdd, tokenUser);
        // 添加动态码信息
        addByCode(empInfoAndRuleAddDTO.getCode(), empInfoVO);
        EmpAllInfoDTO empAllInfoDTO = empInfoAndRuleAddDTO.to(EmpAllInfoDTO.class);
        // 员工设置字段赋值，家庭成员+紧急联系人
        saveTemplateFieldData(empInfoVO.getId(), empInfoAndRuleAddDTO, tokenUser);
        // 自定义字段赋值
        saveAdditionalField(empInfoAndRuleAddDTO.getAddEmpFieldList(), empInfoAndRuleAddDTO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 发布关联信息
        publishEmpRelation(empAllInfoDTO, empInfoVO, tokenUser);
        // 待入职发起审批
        addApprove(empInfoAndRuleAddDTO, empInfoVO, tokenUser);

        // 开通用户
        if (StringUtils.isEmpty(empInfoVO.getUserId())) {
            userProviderService.registerAccount(empInfoVO.getName(), empInfoVO.getPhone(), tokenUser, empInfoVO.getCompanyId());
        }
        String userName;
        if (null != tokenUser.getUserName()) {
            userName = tokenUser.getUserName();
        } else {
            userName = "扫码入职";
        }

        String desc = PersonalEventExample.INSERT_INTO_ADMIN + userName + PersonalEventExample.INSERT_INTO_SYS;
        personalEventService.autoSave(empInfoVO, tokenUser, desc, PersonalEventEnum.ADD.getValue(), PersonalEventEnum.ADD.getDesc());//添加花名册
        HrLogKit.logForSave("完善入职员工信息,员工姓名:" + empInfoVO.getName(),
                "saveEmpAllInfo", empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);
        // 记录今日新增
        operationEmpRecordAdd(empInfoAndRuleAddDTO, tokenUser, empInfoVO);
        // 初始化员工社保相关信息
        empSocRelatedService.initRelatedByEmpId(empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = new ArrayList<>();
        list.add(empInfoVO.getId());
        empCompleteInfo(list, tokenUser);

        return empInfoVO;
    }

    /**
     * 为入职模板中的字段添加数据，家庭成员+紧急联系人
     */
    private void saveTemplateFieldData(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        // 任何一个家庭成员信息不为空就创建家庭成员记录 hr_emp_family表
        saveFamily(empId, empInfoAndRuleAddDTO, tokenUser);

        // 任何一个紧急联系人信息不为空就创建联系人记录 hr_emp_contacts表
        saveContacts(empId, empInfoAndRuleAddDTO, tokenUser);

        // 保存 奖惩记录 hr_emp_reward_punish表
        saveRewardsPunishments(empId, empInfoAndRuleAddDTO, tokenUser);

        // 保存教育经历 hr_emp_education表
        saveEducation(empId, empInfoAndRuleAddDTO, tokenUser);

        // 保存工作经历 hr_emp_work表
        saveEmpWork(empId, empInfoAndRuleAddDTO, tokenUser);

        // 保存培训经历 hr_emp_train表
        saveEmpTrain(empId, empInfoAndRuleAddDTO, tokenUser);

    }

    private void saveEmpTrain(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        boolean flag = saveEmpTrainFlag(empInfoAndRuleAddDTO);
        if (flag) {
            EmpTrainAddDTO empTrainAddDTO = empInfoAndRuleAddDTO.to(EmpTrainAddDTO.class);
            empTrainAddDTO.setStartTime(empInfoAndRuleAddDTO.getTrainStartTime());
            empTrainAddDTO.setEndTime(empInfoAndRuleAddDTO.getTrainEndTime());
            empTrainAddDTO.setEmpId(empId);
            empTrainService.save(empTrainAddDTO, tokenUser);
        }
    }

    private boolean saveEmpTrainFlag(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        return StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainCourse())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainStartTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainEndTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainDuration())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainOrgName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getAssessResult())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainAddress())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainMode())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainCerName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTrainCerNumber())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getRemake())
                ;
    }

    private void saveEmpWork(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        boolean flag = saveEmpWorkFlag(empInfoAndRuleAddDTO);
        if (flag) {
            EmpWorkAddDTO empWorkAddDTO = empInfoAndRuleAddDTO.to(EmpWorkAddDTO.class);
            empWorkAddDTO.setStartTime(empInfoAndRuleAddDTO.getWorkStartTime());
            empWorkAddDTO.setEndTime(empInfoAndRuleAddDTO.getWorkEndTime());
            empWorkAddDTO.setRemark(empInfoAndRuleAddDTO.getWorkRemark());
            empWorkAddDTO.setEmpId(empId);
            empWorkService.save(empWorkAddDTO, tokenUser);
        }
    }

    private boolean saveEmpWorkFlag(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        return StrKit.isNotEmpty(empInfoAndRuleAddDTO.getCompany())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getPosition())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getWorkStartTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getWorkEndTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getLeaveReason())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getLeaveSalary())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getWorkRemark())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getWitName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getWitPhone())
                ;
    }

    private void saveEducation(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO,
                               TokenUser tokenUser) {
        boolean flag = saveEducationFlag(empInfoAndRuleAddDTO);
        if (flag) {
            EmpEducationAddDTO empEducationAddDTO =
                    empInfoAndRuleAddDTO.to(EmpEducationAddDTO.class);
            empEducationAddDTO.setStartTime(empInfoAndRuleAddDTO.getEduStartTime());
            empEducationAddDTO.setEndTime(empInfoAndRuleAddDTO.getEduEndTime());
            empEducationAddDTO.setEmpId(empId);
            empEducationService.save(empEducationAddDTO, tokenUser);
        }
    }

    private boolean saveEducationFlag(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        return StrKit.isNotEmpty(empInfoAndRuleAddDTO.getEducation())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getGraCollege())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getMajor())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getEduStartTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getEduEndTime())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getTeaMethods())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getGraCerNumber())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getDegreeType())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getDegreeName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getDegreeNumber())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getEducationRemark())
                ;
    }

    /**
     * 保存奖惩信息
     *
     * @param empId
     * @param empInfoAndRuleAddDTO
     * @param tokenUser
     */
    private void saveRewardsPunishments(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO,
                                        TokenUser tokenUser) {
        //判断是否有奖惩信息
        boolean flag = saveRewardsPunishmentsFlag(empInfoAndRuleAddDTO);
        if (flag) {
            EmpRewardPunishAddDTO empRewardPunishAddDTO =
                    empInfoAndRuleAddDTO.to(EmpRewardPunishAddDTO.class);
            empRewardPunishAddDTO.setRemark(empInfoAndRuleAddDTO.getRewardsRemark());
            empRewardPunishAddDTO.setEmpId(empId);
            empRewardPunishService.save(empRewardPunishAddDTO, tokenUser);
        }
    }

    private boolean saveRewardsPunishmentsFlag(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO) {
        return StrKit.isNotEmpty(empInfoAndRuleAddDTO.getRewardPunish())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getRewardType())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getPunishType())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getHandleDate())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getContent())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getAmount())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getReason())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getRewardsRemark())
                ;
    }

    /**
     * 新建家庭成员信息
     */
    private void saveFamily(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        // 任何一个家庭成员信息不为空就创建家庭成员记录
        if (StrKit.isNotEmpty(empInfoAndRuleAddDTO.getFamilyName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getFamilyPhone())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getFamilyRelation())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getFamilyWorkUnit())) {
            // 处理家庭成员
            EmpFamilyAddDTO empFamilyAddDTO = new EmpFamilyAddDTO();
            empFamilyAddDTO.setEmpId(empId);
            empFamilyAddDTO.setName(empInfoAndRuleAddDTO.getFamilyName());
            empFamilyAddDTO.setPhone(empInfoAndRuleAddDTO.getFamilyPhone());
            empFamilyAddDTO.setCompanyId(empInfoAndRuleAddDTO.getCompanyId());
            empFamilyAddDTO.setRelation(empInfoAndRuleAddDTO.getFamilyRelation());
            empFamilyAddDTO.setWorkUnit(empInfoAndRuleAddDTO.getFamilyWorkUnit());
            empFamilyService.save(empFamilyAddDTO, tokenUser);
        }
    }

    /**
     * 新建家庭成员信息
     */
    private void saveContacts(String empId, EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        // 任何一个紧急联系人信息不为空就创建联系人记录
        if (StrKit.isNotEmpty(empInfoAndRuleAddDTO.getContactsName())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getContactsPhone())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getContactsRelation())
                || StrKit.isNotEmpty(empInfoAndRuleAddDTO.getContactsAddress())) {
            // 处理紧急联系人
            EmpContactsAddDTO empContactsAddDTO = new EmpContactsAddDTO();
            empContactsAddDTO.setEmpId(empId);
            empContactsAddDTO.setCompanyId(empInfoAndRuleAddDTO.getCompanyId());
            empContactsAddDTO.setName(empInfoAndRuleAddDTO.getContactsName());
            empContactsAddDTO.setPhone(empInfoAndRuleAddDTO.getContactsPhone());
            empContactsAddDTO.setRelation(empInfoAndRuleAddDTO.getContactsRelation());
            empContactsAddDTO.setAddress(empInfoAndRuleAddDTO.getContactsAddress());
            empContactsService.save(empContactsAddDTO, tokenUser);
        }
    }

    /**
     * 处理家庭成员+紧急联系人信息
     */
    private void processFamilyAndContacts(EmpInfoUpdateDTO empInfoUpdateDTO, TokenUser tokenUser) {
        String empId = empInfoUpdateDTO.getId();
        if (StrKit.isNotEmpty(empInfoUpdateDTO.getFamilyName())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getFamilyPhone())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getFamilyRelation())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getFamilyWorkUnit())) {
            // 处理家庭成员
            List<EmpFamilyDO> empFamilyDOS = empFamilyService.listByEmpId(empId, tokenUser.getSiteId());
            // 之前有家庭成员记录：修改；无记录：新增
            if (CollectionUtils.isEmpty(empFamilyDOS)) {
                saveFamily(empId, empInfoUpdateDTO.to(EmpInfoAndRuleAddDTO.class), tokenUser);
            } else {
                EmpFamilyDO empFamilyDO = empFamilyDOS.get(0);
                empFamilyDO.setName(empInfoUpdateDTO.getFamilyName());
                empFamilyDO.setPhone(empInfoUpdateDTO.getFamilyPhone());
                empFamilyDO.setRelation(empInfoUpdateDTO.getFamilyRelation());
                empFamilyDO.setWorkUnit(empInfoUpdateDTO.getFamilyWorkUnit());
                empFamilyService.updateById(empFamilyDO, tokenUser.getSiteId(), tokenUser.getUserId());
            }
        }
        // 处理紧急联系人
        if (StrKit.isNotEmpty(empInfoUpdateDTO.getContactsName())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getContactsPhone())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getContactsRelation())
                || StrKit.isNotEmpty(empInfoUpdateDTO.getContactsAddress())) {
            List<EmpContactsDO> empContactsDOS = empContactsService.listByEmpId(empId, tokenUser.getSiteId());
            if (CollectionUtils.isEmpty(empContactsDOS)) {
                saveContacts(empId, empInfoUpdateDTO.to(EmpInfoAndRuleAddDTO.class), tokenUser);
            } else {
                EmpContactsDO empContactsDO = empContactsDOS.get(0);
                empContactsDO.setName(empInfoUpdateDTO.getContactsName());
                empContactsDO.setPhone(empInfoUpdateDTO.getContactsPhone());
                empContactsDO.setRelation(empInfoUpdateDTO.getContactsRelation());
                empContactsDO.setAddress(empInfoUpdateDTO.getContactsAddress());
                empContactsService.updateById(empContactsDO, tokenUser.getSiteId(), tokenUser.getUserId());
            }
        }
    }

    /**
     * 记录今日新增
     */
    private void operationEmpRecordAdd(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser, EmpInfoVO empInfoVO) {
        // 员工端小程序deviceType
        List<DictItemDO> empDictItem = adminProviderService.selectByDictCode("1217");
        List<String> empDeviceType = empDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        // 管理端小程序deviceType
        List<DictItemDO> adminDictItem = adminProviderService.selectByDictCode("1218");
        List<String> adminDeviceType = adminDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        // PC端deviceType
        List<DictItemDO> pcDictItem = adminProviderService.selectByDictCode("1219");
        List<String> pcDeviceType = pcDictItem.stream()
                .map(DictItemDO::getDictItemValue).collect(Collectors.toList());
        try {
            if (empInfoVO != null) {
                HttpServletRequest request = ((ServletRequestAttributes) Objects.requireNonNull(RequestContextHolder.getRequestAttributes())).getRequest();
                String deviceType = request.getHeader("devicetype");
                OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
                operationEmpRecordAddDTO.setQueryType(2);
                operationEmpRecordAddDTO.setUserId(empInfoVO.getUserId());
                operationEmpRecordAddDTO.setEmpId(empInfoVO.getId());
                operationEmpRecordAddDTO.setCompanyId(empInfoVO.getCompanyId());
                if (pcDeviceType.contains(deviceType)) {
                    if (empInfoAndRuleAddDTO.getCheckInId() == null) {
                        if (empInfoVO.getStatus() == 2) {
                            operationEmpRecordAddDTO.setSourceTypeInfo("PC入职");
                        } else if (empInfoVO.getStatus() == 1) {
                            operationEmpRecordAddDTO.setSourceTypeInfo("PC待入职");
                        }
                        operationEmpRecordAddDTO.setEmpStatus(2);
                        operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                        operationEmpRecordAddDTO.setSourceType(1);
                    } else if (empInfoAndRuleAddDTO.getCheckInId() != null) {

                        if (empInfoAndRuleAddDTO.getStatus() == 2) {
                            operationEmpRecordAddDTO.setSourceTypeInfo("预登记转入职");
                            operationEmpRecordAddDTO.setEmpStatus(3);
                        } else if (empInfoAndRuleAddDTO.getStatus() == 1) {
                            operationEmpRecordAddDTO.setSourceTypeInfo("预登记转待入职");
                            operationEmpRecordAddDTO.setEmpStatus(2);
                        }
                        operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());

                        OperationEmpRecordAddDTO operationEmpRecordAddDTO1 = new OperationEmpRecordAddDTO();
                        operationEmpRecordAddDTO1.setCompanyId(empInfoVO.getCompanyId());
                        operationEmpRecordAddDTO1.setQueryType(2);
                        operationEmpRecordAddDTO1.setInputUserId(tokenUser.getUserId());
                        operationEmpRecordAddDTO1.setUserId(empInfoVO.getUserId());
                        operationEmpRecordAddDTO1.setEmpId(empInfoVO.getId());
                        if (empInfoAndRuleAddDTO.getStatus() == 2) {
                            operationEmpRecordAddDTO1.setEmpStatus(3);
                            operationEmpRecordAddDTO1.setSourceTypeInfo("PC入职");
                        } else if (empInfoAndRuleAddDTO.getStatus() == 1) {
                            operationEmpRecordAddDTO.setSourceTypeInfo("PC待入职");
                            operationEmpRecordAddDTO.setEmpStatus(2);
                        }
                        OperationEmpRecordQuery operationEmpRecordQuery = new OperationEmpRecordQuery();
                        operationEmpRecordQuery.setEmpStatus(1);
                        operationEmpRecordQuery.setCheckInId(empInfoAndRuleAddDTO.getCheckInId());
                        List<OperationEmpRecordListVO> select = operationEmpRecordService.select(operationEmpRecordQuery, tokenUser.getSiteId());
                        for (OperationEmpRecordListVO operationEmpRecordListVO : select) {
                            operationEmpRecordAddDTO1.setSourceType(operationEmpRecordListVO.getSourceType());
                        }
                        operationEmpRecordAddDTO1.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpInfoAndRule");
                        operationEmpRecordService.save(operationEmpRecordAddDTO1, tokenUser);
                    }
                    operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpInfoAndRule");
                    operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
                } else if (empDeviceType.contains(deviceType)) {
                    if (empInfoVO.getStatus() == 1) {
                        operationEmpRecordAddDTO.setInputUserId(empInfoAndRuleAddDTO.getOperationUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序待入职");
                    } else if (empInfoVO.getStatus() == 2) {
                        operationEmpRecordAddDTO.setInputUserId(empInfoAndRuleAddDTO.getOperationUserId());
                        operationEmpRecordAddDTO.setEmpStatus(3);
                        operationEmpRecordAddDTO.setSourceType(2);
                        operationEmpRecordAddDTO.setSourceTypeInfo("小程序入职");
                    }
                    operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpInfoAndRule");
                    operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
                } else if (adminDeviceType.contains(deviceType)) {
                    operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                    operationEmpRecordAddDTO.setEmpStatus(2);
                    operationEmpRecordAddDTO.setSourceType(2);
                    operationEmpRecordAddDTO.setSourceTypeInfo("小程序管理端待入职");
                    operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveEmpInfoAndRule");
                    operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
                }

            }
        } catch (Exception e) {
            log.error("员工记录异常");
        }
    }

    /**
     * 保存自定义字段值
     *
     * @param addEmpFieldList 自定义字段列表
     * @param tokenUser       当前用户
     */
    private void saveAdditionalField(List<AddEmpFieldDTO> addEmpFieldList, String companyId, String empId, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(addEmpFieldList)) {
            return;
        }
        List<Long> idList = addEmpFieldList.parallelStream().map(AddEmpFieldDTO::getId).collect(Collectors.toList());
        List<CompanyAdditionalFieldsDO> companyAdditionalFieldsDOS = companyAdditionalFieldsService.selectByIdList(idList, tokenUser);
        // id-字段 Map
        Map<Long, CompanyAdditionalFieldsDO> idFieldsMap = companyAdditionalFieldsDOS.parallelStream()
                .collect(Collectors.toMap(CompanyAdditionalFieldsDO::getId, v -> v));
        // 员工自定字段所填值
        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empAdditionalFieldsService
                .selectByCompanyIdEmpIdAndFieldIds(companyId, empId, new ArrayList<>(idFieldsMap.keySet()));
        // 字段Id为key
        Map<Long, EmpAdditionalFieldsDO> fieldIdDOMap = empAdditionalFieldsDOList.parallelStream()
                .collect(Collectors.toMap(EmpAdditionalFieldsDO::getFieldId, v -> v, (v1, v2) -> v1));
        for (AddEmpFieldDTO addEmpFieldDTO : addEmpFieldList) {
            CompanyAdditionalFieldsDO companyAdditionalFieldsDO = idFieldsMap.get(addEmpFieldDTO.getId());
            if (companyAdditionalFieldsDO == null) {
                throw new ParamException("自定义字段【" + addEmpFieldDTO.getFieldName() + "】不存在");
            }

            if (Boolean.FALSE.equals(companyAdditionalFieldsDO.getIsOpen())) {
                throw new ParamException("自定义字段【" + companyAdditionalFieldsDO.getFieldName() + "】未开启，无需填写");
            }
            EmpAdditionalFieldsDO empAdditionalFieldsDO = fieldIdDOMap.get(addEmpFieldDTO.getId());
            if (empAdditionalFieldsDO == null) {
                // 不存在自定义值 新建
                EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO = new EmpAdditionalFieldsAddDTO();
                empAdditionalFieldsAddDTO.setModuleCode(companyAdditionalFieldsDO.getModuleCode());
                empAdditionalFieldsAddDTO.setCompanyId(companyId);
                empAdditionalFieldsAddDTO.setFieldId(companyAdditionalFieldsDO.getId());
                empAdditionalFieldsAddDTO.setContent(addEmpFieldDTO.getContent());
                empAdditionalFieldsAddDTO.setEmpId(empId);
                empAdditionalFieldsAddDTO.setType(1);
                empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
            } else {
                // 存在自定义值 更新
                EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO = new EmpAdditionalFieldsUpdateDTO();
                empAdditionalFieldsUpdateDTO.setId(empAdditionalFieldsDO.getId());
                empAdditionalFieldsUpdateDTO.setModuleCode(companyAdditionalFieldsDO.getModuleCode());
                empAdditionalFieldsUpdateDTO.setCompanyId(companyId);
                empAdditionalFieldsUpdateDTO.setFieldId(companyAdditionalFieldsDO.getId());
                empAdditionalFieldsUpdateDTO.setContent(addEmpFieldDTO.getContent());
                empAdditionalFieldsUpdateDTO.setEmpId(empId);
                empAdditionalFieldsUpdateDTO.setType(1);
                empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
            }
        }
    }

    /**
     * 校验是否是预登记人员
     */
    private void addCheckInPeople(EmpAllInfoAddDTO empAllInfoAddDTO, TokenUser tokenUser) {

        try {
            String checkInId = empAllInfoAddDTO.getCheckInId();
            if (StrKit.isNotEmpty(checkInId)) {
                CheckInPeopleVO checkInPeopleVO = checkInPeopleService.selectById(checkInId, tokenUser.getSiteId());
                if (Objects.nonNull(checkInPeopleVO)) {
                    // 如果 民族/出生日期/住址/签发机关/开始时间/结束时间/身份证照片 任意一个不为空，就创建这个公司的员工设置
                    if (Objects.nonNull(checkInPeopleVO.getNation())
                            || Objects.nonNull(checkInPeopleVO.getBirthday())
                            || Objects.nonNull(checkInPeopleVO.getAddress())
                            || Objects.nonNull(checkInPeopleVO.getIssuedBy())
                            || Objects.nonNull(checkInPeopleVO.getStartDate())
                            || Objects.nonNull(checkInPeopleVO.getEndDate())
                            || Objects.nonNull(checkInPeopleVO.getPhoto())) {
                        companyNecessaryFieldService.checkInAddNecessaryField(empAllInfoAddDTO.getCompanyId(), tokenUser);
                        if (StrKit.isNotEmpty(checkInPeopleVO.getNation())) {
                            empAllInfoAddDTO.setNation(checkInPeopleVO.getNation());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getIssuedBy())) {
                            empAllInfoAddDTO.setIssuedBy(checkInPeopleVO.getIssuedBy());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getStartDate())) {
                            empAllInfoAddDTO.setCardStartDate(checkInPeopleVO.getStartDate());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getEndDate())) {
                            empAllInfoAddDTO.setCardEndDate(checkInPeopleVO.getEndDate());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getPhoto())) {
                            empAllInfoAddDTO.setAnnexPersonPhoto(checkInPeopleVO.getPhoto());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getAddress())) {
                            empAllInfoAddDTO.setNativeLocation(checkInPeopleVO.getAddress());
                        }
                        if (StrKit.isNotEmpty(checkInPeopleVO.getBirthday())) {
                            empAllInfoAddDTO.setBirthday(checkInPeopleVO.getBirthday());
                        }
                    }
                }
            }
        } catch (Exception e) {
            log.error("预登记人员入职失败，错误信息：{}", e.getMessage());
        }
    }

    /**
     * 动态码录入员工列表
     */
    private void addByCode(String code, EmpInfoVO empInfoVO) {
        if (StrKit.isEmpty(code)) {
            return;
        }
        String key = CacheKeyKit.getDynamicCode(code);
        DynamicCodeVO dynamicCodeVO = cache.get(key);
        if (Objects.isNull(dynamicCodeVO)) {
            return;
        }
        // 不是添加员工的动态码就不记录
        if (!HrConstants.TYPE_EMP.equals(dynamicCodeVO.getType())) {
            return;
        }
        List<EmpInfoVO> list;
        if (CollectionUtils.isEmpty(dynamicCodeVO.getEmpInfoVOList())) {
            list = new ArrayList<>();
        } else {
            list = dynamicCodeVO.getEmpInfoVOList();
        }
        list.add(empInfoVO);
        dynamicCodeVO.setEmpInfoVOList(list);
        // 有效时间
        long ttl = cache.ttl(key);
        // key失效
        if (ttl != -1 && ttl != -2) {
            // 因为是重新写入,有效时间可能会稍微多一点
            cache.set(key, dynamicCodeVO, ttl * 1000);
            log.info("通过动态码添加一位员工,code:{},人员信息:{}", code, JSON.toJSONString(empInfoVO));
        }
    }

    /**
     * 待入职发起审批
     */
    private void addApprove(EmpAllInfoAddDTO empAllInfoAddDTO, EmpInfoVO empInfoVO, TokenUser tokenUser) {
        // 校验审批流程id
        checkAppro(empAllInfoAddDTO, tokenUser);
        // 待入职并且有审批模板的才发起审批
        if (!WAIT_ENTRY.getValue().equals(empAllInfoAddDTO.getStatus())
                || StrKit.isEmpty(empAllInfoAddDTO.getFlowId())) {
            return;
        }
        String approCompanyId = empAllInfoAddDTO.getCompanyId();
        // 指定的审批id
        String flowId = empAllInfoAddDTO.getFlowId();

        NewApproDTO newApproDTO = new NewApproDTO();
        // 这里可以放置一些自定义的数据，前端在绘制审批明细时使用。假如这里放置是账单对象
        newApproDTO.setProps(JsonKit.toJSONString(empInfoVO));
        // 审批的标题
        newApproDTO.setTitle(empInfoVO.getName() + "的待入职审批");
        // 审批关联的业务类型，约定账单的subjectType是costBill
        newApproDTO.setSubjectType(HrConstants.SUBJECT_TYPE_HR_ON_JOB);
        // 审批关联的业务id，账单id，可以利用这个到时可以根据账单id查询该账单的所有审批历史
        newApproDTO.setSubjectId(empInfoVO.getId());
        // 设置审批的流程id，costBillAppro是超级后台设置的账单审批类型的code
        if (!approProviderService.checkFlowId(HrConstants.APPROVE_ON_JOB, approCompanyId, flowId, tokenUser)) {
            throw new ParamException("审批流程错误,请联系管理员");
        }
        newApproDTO.setFlowId(flowId);
        // costBillDO的所有属性会匹配审批表单里的字段，匹配到了就会设置在审批表单里
        newApproDTO.setPojo(empInfoVO);
        // 发起审批
        UserApproVO userApproVO = approProviderService.addUserAppro(newApproDTO, tokenUser);
        EmpInfoDO empInfoDO = new EmpInfoDO();
        empInfoDO.setId(empInfoVO.getId());
        empInfoDO.setApprovalStatus(ApprovalStatusEnum.APPRO_ING.getValue());
        updateByIdSelective(empInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
    }

    private void addRule(EmpInfoAndRuleAddDTO empInfoAndRuleAddDTO, TokenUser tokenUser) {
        // 判断是否需要新增工价规则
        SalaryCalculateRuleVO salaryRuleVO = salaryCalculateRuleService.
                selectById(empInfoAndRuleAddDTO.getSalaryRuleId(), tokenUser.getSiteId());
        if (Objects.nonNull(salaryRuleVO) && !CalculatePayConstant.RULE_TYPE_EQUALLY.equals(salaryRuleVO.getRuleType())) {
            SalaryCalculateRuleAddDTO salaryRuleAdd = empInfoAndRuleAddDTO.getSalaryRuleAddDTO();
            boolean noAddSalaryRule = salaryRuleVO.getHourAmount() == null ?
                    salaryRuleAdd.getHourAmountDouble() == null : salaryRuleVO.getHourAmount() == Math.round(salaryRuleAdd.getHourAmountDouble() * 100);
            if (noAddSalaryRule) {
                noAddSalaryRule = salaryRuleVO.getHourAmountRule() == null ?
                        salaryRuleAdd.getHourAmountRule() == null : salaryRuleVO.getHourAmountRule().equals(salaryRuleAdd.getHourAmountRule());
            }
            if (noAddSalaryRule) {
                noAddSalaryRule = salaryRuleVO.getRedPacketRule() == null ?
                        salaryRuleAdd.getRedPacketRule() == null : salaryRuleVO.getRedPacketRule().equals(salaryRuleAdd.getRedPacketRule());
            }
            if (noAddSalaryRule) {
                noAddSalaryRule = salaryRuleVO.getLeaveOfficeRule() == null ?
                        salaryRuleAdd.getLeaveOfficeRule() == null : salaryRuleVO.getLeaveOfficeRule().equals(salaryRuleAdd.getLeaveOfficeRule());
            }
            if (!noAddSalaryRule) {
                // 新增工价规则
                salaryRuleAdd.setName(buildRuleName(empInfoAndRuleAddDTO.getSalaryRuleAddDTO(),
                        CalculatePayConstant.RULE_TYPE_MAN_HOUR));
                salaryRuleAdd.setRuleType(CalculatePayConstant.RULE_TYPE_MAN_HOUR);
                SalaryCalculateRuleVO saveSalaryRule = salaryCalculateRuleService.save(salaryRuleAdd, tokenUser);
                empInfoAndRuleAddDTO.setSalaryRuleId(saveSalaryRule.getId());
            }
        }
        // 判断是否需要新增劳务费规则
        SalaryCalculateRuleVO serviceFeeRuleVO = salaryCalculateRuleService.
                selectById(empInfoAndRuleAddDTO.getServiceFeeRuleId(), tokenUser.getSiteId());
        if (Objects.nonNull(serviceFeeRuleVO) && !CalculatePayConstant.RULE_TYPE_EQUALLY.equals(serviceFeeRuleVO.getRuleType())) {
            SalaryCalculateRuleAddDTO serviceFeeRuleAdd = empInfoAndRuleAddDTO.getServiceFeeRuleAddDTO();
            if (Objects.isNull(serviceFeeRuleAdd)) {
                return;
            }
            boolean noAddSalaryRule = serviceFeeRuleVO.getHourAmount() == null ?
                    serviceFeeRuleAdd.getHourAmountDouble() == null : serviceFeeRuleVO.getHourAmount() == serviceFeeRuleAdd.getHourAmountDouble() * 100;
            if (noAddSalaryRule) {
                noAddSalaryRule = serviceFeeRuleVO.getHourAmountRule() == null ?
                        serviceFeeRuleAdd.getHourAmountRule() == null :
                        serviceFeeRuleVO.getHourAmountRule().equals(serviceFeeRuleAdd.getHourAmountRule());
            }
            if (noAddSalaryRule) {
                noAddSalaryRule = serviceFeeRuleVO.getRedPacketRule() == null ?
                        serviceFeeRuleAdd.getRedPacketRule() == null :
                        serviceFeeRuleVO.getRedPacketRule().equals(serviceFeeRuleAdd.getRedPacketRule());
            }
            if (noAddSalaryRule) {
                noAddSalaryRule = serviceFeeRuleVO.getLeaveOfficeRule() == null ?
                        serviceFeeRuleAdd.getLeaveOfficeRule() == null :
                        serviceFeeRuleVO.getLeaveOfficeRule().equals(serviceFeeRuleAdd.getLeaveOfficeRule());
            }
            if (noAddSalaryRule) {
                noAddSalaryRule = serviceFeeRuleVO.getSpecialCost() == null ?
                        serviceFeeRuleAdd.getSpecialCostDouble() == null :
                        serviceFeeRuleVO.getSpecialCost() == serviceFeeRuleAdd.getSpecialCostDouble() * 100;
            }
            if (!noAddSalaryRule) {
                // 新增劳务费规则
                serviceFeeRuleAdd.setName(buildRuleName(empInfoAndRuleAddDTO.getServiceFeeRuleAddDTO(),
                        CalculatePayConstant.RULE_TYPE_COMMISSION));
                serviceFeeRuleAdd.setRuleType(CalculatePayConstant.RULE_TYPE_COMMISSION);
                SalaryCalculateRuleVO saveSalaryRule = salaryCalculateRuleService.save(serviceFeeRuleAdd, tokenUser);
                empInfoAndRuleAddDTO.setServiceFeeRuleId(saveSalaryRule.getId());
            }
        }
    }

    @Override
    public String buildRuleName(SalaryCalculateRuleAddDTO salaryCalculateRuleAddDTO, Integer type) {
        StringBuilder salaryName = new StringBuilder();
        // 根据规则生成姓名
        if (Objects.isNull(salaryCalculateRuleAddDTO)) {
            return "";
        }
        // 判断类型
        boolean isManHour = type.equals(CalculatePayConstant.RULE_TYPE_MAN_HOUR);
        // 拼装工价规则
        if (StrKit.isNotEmpty(salaryCalculateRuleAddDTO.getHourAmountDouble())) {
            salaryName.append(salaryCalculateRuleAddDTO.getHourAmountDouble())
                    .append("元/小时");
            if (StrKit.isNotEmpty(salaryCalculateRuleAddDTO.getHourAmountRule())) {
                List<HourAmountRule> hourAmountRuleList = JSON.parseArray(salaryCalculateRuleAddDTO.getHourAmountRule(),
                        HourAmountRule.class);
                HourAmountRule hourAmountRule;
                for (HourAmountRule amountRule : hourAmountRuleList) {
                    hourAmountRule = amountRule;
                    boolean isUnits = CalculatePayConstant.HOUR_RULE_TYPE_UNIT.equals(hourAmountRule.getType());
                    String unitsString = isUnits ?
                            hourAmountRule.getUnits().equals(CalculatePayConstant.UNIT_MONTH) ?
                                    "月" : hourAmountRule.getUnits().equals(CalculatePayConstant.UNIT_DAY) ?
                                    "天" : "工时" : "";
                    salaryName.append("+");
                    if (isUnits) {
                        salaryName.append("入职满")
                                .append(hourAmountRule.getNumber())
                                .append(unitsString);
                    } else {
                        salaryName.append("自")
                                .append(hourAmountRule.getTime());
                    }
                    salaryName.append(isManHour ? "工价变为：" : "抽成变为：")
                            .append(hourAmountRule.getNewHourAmount())
                            .append("元/小时");
                }
            }
        }
        // 拼装红包规则
        if (StrKit.isNotEmpty(salaryCalculateRuleAddDTO.getRedPacketRule())) {
            List<RedPacketRule> redPacketRuleList = JSON.parseArray(salaryCalculateRuleAddDTO.getRedPacketRule(),
                    RedPacketRule.class);
            for (RedPacketRule redPacketRule : redPacketRuleList) {
                String unitsString = redPacketRule.getUnits().equals(CalculatePayConstant.UNIT_MONTH) ?
                        "月" : redPacketRule.getUnits().equals(CalculatePayConstant.UNIT_DAY) ?
                        "天" : "工时";
                salaryName.append("+入职满")
                        .append(redPacketRule.getNumber())
                        .append(unitsString)
                        .append("后，发放一次性红包")
                        .append(redPacketRule.getRedPacketAmount())
                        .append("元");
            }
        }
        // 拼装离职规则
        if (StrKit.isNotEmpty(salaryCalculateRuleAddDTO.getRedPacketRule())) {
            List<LeaveOfficeRule> leaveOfficeRuleList = JSON.parseArray(salaryCalculateRuleAddDTO.getLeaveOfficeRule(),
                    LeaveOfficeRule.class);
            for (LeaveOfficeRule leaveOfficeRule : leaveOfficeRuleList) {
                String unitsString = leaveOfficeRule.getUnits().equals(CalculatePayConstant.UNIT_MONTH) ?
                        "月" : leaveOfficeRule.getUnits().equals(CalculatePayConstant.UNIT_DAY) ?
                        "天" : "工时";
                boolean isDeduct = CalculatePayConstant.LEAVE_DEDUCT.equals(leaveOfficeRule.getType());
                salaryName.append("+不满")
                        .append(leaveOfficeRule.getNumber())
                        .append(unitsString)
                        .append(",");
                if (isDeduct) {
                    salaryName.append("倒扣")
                            .append(leaveOfficeRule.getDeductAmount())
                            .append("元工资");
                } else {
                    salaryName.append("工价变为")
                            .append(leaveOfficeRule.getNewHourAmount())
                            .append("元/小时");
                }
            }
        }
        // 拼装特殊费用
        if (!isManHour &&
                salaryCalculateRuleAddDTO.getSpecialCostDouble() != null &&
                salaryCalculateRuleAddDTO.getSpecialCostDouble() != 0) {
            salaryName.append("+只要工人在职，额外结算")
                    .append(salaryCalculateRuleAddDTO.getSpecialCostDouble())
                    .append("元/月");
        }
        return salaryName.toString();
    }

    private void updataCheckInPeople(String name, String idCard, String channelId, String phone, TokenUser tokenUser, Integer status, String checkInId) {
        //CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(phone, tokenUser.getSiteId());
        CheckInPeopleDO checkInPeopleDO = null;
        if (!StringUtils.isEmpty(checkInId)) {
            checkInPeopleDO = checkInPeopleService.selectById(checkInId, tokenUser.getSiteId()).to(CheckInPeopleDO.class);
        } else {
            checkInPeopleDO = checkInPeopleService.selectByPhone(phone, tokenUser.getSiteId());
        }
        if (checkInPeopleDO != null) {
            if (status == 1) {
                checkInPeopleDO.setStatus(CheckInPeopleConstant.STATUS_TO_BE_EMPLOYED);
            } else {
                checkInPeopleDO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
            }
            checkInPeopleDO.setWorkStatus(CheckInPeopleConstant.WORK_STATUS_RNTRY);
            // 修改该预登记人员的渠道ID最新的
            checkInPeopleDO.setChannelId(channelId);
            // 修改其他信息
            checkInPeopleDO.setPhone(phone);
            checkInPeopleDO.setIdcard(idCard);
            checkInPeopleDO.setName(name);
            checkInPeopleDO.setSource("预登记");
            checkInPeopleService.updateIncludeNull(checkInPeopleDO, tokenUser);
        } else {
            // 新增
            CheckInPeopleAddDTO checkInPeopleAddDTO = new CheckInPeopleAddDTO();
            checkInPeopleAddDTO.setName(name);
            checkInPeopleAddDTO.setPhone(phone);
            checkInPeopleAddDTO.setIdcard(idCard);
            checkInPeopleAddDTO.setChannelId(channelId);
            checkInPeopleAddDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
            checkInPeopleAddDTO.setWorkStatus(CheckInPeopleConstant.WORK_STATUS_RNTRY);
            checkInPeopleAddDTO.setSource(HrConstants.HUW);
            checkInPeopleAddDTO.setFlag(1);
            checkInPeopleService.save(checkInPeopleAddDTO, tokenUser);
        }

    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int updateEmpAllInfo(EmpAllInfoDTO empAllInfoDTO, TokenUser tokenUser) {
        if (empAllInfoDTO.getIdCard() != null) {
            String idCard = empAllInfoDTO.getIdCard();
            // 拿身份证号辨别性别,年龄,身份证号
            if (empAllInfoDTO.getIdCard().length() == 18) {
                empAllInfoDTO.setGender(Integer.parseInt(idCard.substring(16, 17)) % 2 == 0 ? 2 : 1);
                empAllInfoDTO.setEmpAge(Integer.parseInt(DateUtils.getYearAndMonth(new Date())[0]) - Integer.parseInt(idCard.substring(6, 10)));
                empAllInfoDTO.setBirthday(idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14) + " 00:00:00");
            } else if (empAllInfoDTO.getIdCard().length() == 15) {
                empAllInfoDTO.setGender(Integer.parseInt(idCard.substring(13, 14)) % 2 == 0 ? 2 : 1);
                empAllInfoDTO.setEmpAge(Integer.parseInt(DateUtils.getYearAndMonth(new Date())[0]) - Integer.parseInt(idCard.substring(6, 8)) - 1901);
                empAllInfoDTO.setBirthday("19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12) + " 00:00:00");
            }
        }

        EmpInfoVO empInfoVO = selectById(empAllInfoDTO.getId(), tokenUser.getSiteId());
        if (Objects.isNull(empInfoVO)) {
            throw new HrException("员工信息不存在或已删除");
        }
        if (StrKit.isNotEmpty(empAllInfoDTO.getChannelId())) {
            List<ChannelFeeSettlementDetailDO> settlementDetailDOS
                    = salaryProviderService.selectByEmpIdAndDate(empAllInfoDTO.getId(), empAllInfoDTO.getCompanyId(), tokenUser);

            if (!CollectionUtils.isEmpty(settlementDetailDOS)) {
                ChannelVO channelVO = channelService.selectById(empInfoVO.getChannelId(), tokenUser.getSiteId());
                throw new ParamException("该员工原有渠道【" + channelVO.getName() + "】本月已生成渠道结算费用，不可更换渠道");
            }
        }
        EmpInfoUpdateDTO empInfoUpdate = empAllInfoDTO.to(EmpInfoUpdateDTO.class);
        update(empInfoUpdate, tokenUser);

        // 发布关联信息
        publishEmpRelation(empAllInfoDTO, empInfoVO, tokenUser);
        //修改额外字段的信息
        changThings(empAllInfoDTO, tokenUser);
        HrLogKit.logForUpdate("完善入职员工信息,员工姓名:" + empInfoVO.getName(),
                "saveEmpAllInfo", empInfoVO.getId(), empInfoVO.getCompanyId(), tokenUser);
        return 1;
    }

    private void changThings(EmpAllInfoDTO empAllInfoDTO, TokenUser tokenUser) {
        //基本信息额外信息
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getCompanyAdditionalFieldsListBasicVOList())) {
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO :
                    empAllInfoDTO.getCompanyAdditionalFieldsListBasicVOList()) {
                if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO() != null) {
                    if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().getId() == null) {
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsAddDTO.class);
                        empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
                    } else {
                        EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsUpdateDTO.class);
                        empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
                    }
                }
            }

        }
        //联系信息额外信息
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getCompanyAdditionalFieldsListContactVOList())) {
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO :
                    empAllInfoDTO.getCompanyAdditionalFieldsListContactVOList()) {
                if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO() != null) {
                    if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().getId() == null) {
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsAddDTO.class);
                        empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
                    } else {
                        EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsUpdateDTO.class);
                        empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
                    }
                }
            }
        }
        //附件额外信息
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getCompanyAdditionalFieldsListAttachmentVOList())) {
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO :
                    empAllInfoDTO.getCompanyAdditionalFieldsListAttachmentVOList()) {
                if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO() != null) {
                    if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().getId() == null) {
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsAddDTO.class);
                        empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
                    } else {
                        EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsUpdateDTO.class);
                        empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
                    }
                }
            }
        }
        //员工档案资料额外信息
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getCompanyAdditionalFieldsListArchiveVOList())) {
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO :
                    empAllInfoDTO.getCompanyAdditionalFieldsListArchiveVOList()) {
                if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO() != null) {
                    if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().getId() == null) {
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsAddDTO.class);
                        empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
                    } else {
                        EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsUpdateDTO.class);
                        empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
                    }
                }
            }
        }
        //员工离职资料
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getCompanyAdditionalFieldsListLeaveOfficeVOList())) {
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO :
                    empAllInfoDTO.getCompanyAdditionalFieldsListLeaveOfficeVOList()) {
                if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO() != null) {
                    if (companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().getId() == null) {
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsAddDTO.class);
                        empAdditionalFieldsService.save(empAdditionalFieldsAddDTO, tokenUser);
                    } else {
                        EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO =
                                companyAdditionalFieldsListVO.getEmpAdditionalFieldsVO().to(EmpAdditionalFieldsUpdateDTO.class);
                        empAdditionalFieldsService.update(empAdditionalFieldsUpdateDTO, tokenUser);
                    }
                }
            }
        }

    }

    @Override
    public EmpInfoVO selectByPhone(String companyId, String phone, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("phone", phone)
                .andEqualTo("siteId", siteId)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId);
        EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
        if (Objects.isNull(empInfoDO)) {
            return null;
        }
        return empInfoDO.to(EmpInfoVO.class);
    }

    @Override
    public EmpInfoDO selectOnJobByPhoneExcludeCompanyId(String excludeCompanyId, String phone, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("phone", phone)
                .andEqualTo("siteId", siteId)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("valid", true)
                .andNotEqualTo("companyId", excludeCompanyId);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public EmpInfoVO selectByNumber(String companyId, String number, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("number", number)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId);
        EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
        if (Objects.isNull(empInfoDO)) {
            return null;
        }
        return empInfoDO.to(EmpInfoVO.class);
    }

    @Override
    public List<EmpInfoListVO> listEntryByPhone(String phone, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("phone", phone)
                .andEqualTo("status", WAIT_ENTRY.getValue())
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        return getVoListByDoList(empInfoDAO.selectByExample(example));
    }

    @Override
    public List<EmpInfoListVO> listByUnionId(String unionId, Integer status) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("unionId", unionId)
                .andEqualTo("status", status)
                .andEqualTo("valid", true);

        return getVoListByDoList(empInfoDAO.selectByExample(example));
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void passEmpAppro(String empId, String type, TokenUser tokenUser) {

        // 根据审批类型查询查询条件
        Example example = buildExampleByApproType(empId, type);
        if (example == null) {
            return;
        }

        // 审批成功
        EmpInfoDO empInfoUp = new EmpInfoDO();
        empInfoUp.setApprovalStatus(ApprovalStatusEnum.APPRO_SUCCESS.getValue());
        if (ApproType.LEAVING.getValue().equals(type)) {
            // 离职,状态改为待离职
            empInfoUp.setStatus(EmpInfoStatus.WAIT_QUIT.getValue());

        }

        // 修改
        empInfoDAO.updateByExampleSelective(empInfoUp, example);
    }

    /**
     * 根据审批类型查询查询条件
     *
     * @param empId 员工id
     * @param type  审批类型
     * @return 查询条件
     */
    private Example buildExampleByApproType(String empId, String type) {
        int status;
        if (ApproType.ON_JOB.getValue().equals(type)) {
            // 入职,待入职
            status = WAIT_ENTRY.getValue();
        } else if (ApproType.TURN_STRAIGHT.getValue().equals(type)) {
            // 转正,入职
            status = HAS_ENTRY.getValue();
        } else if (ApproType.TRANSFER_DUTY.getValue().equals(type)) {
            // 调岗,入职
            status = HAS_ENTRY.getValue();
        } else if (ApproType.LEAVING.getValue().equals(type)) {
            // 离职,入职
            status = EmpInfoStatus.WAIT_QUIT.getValue();
        } else {
            return null;
        }

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("id", empId)
                .andEqualTo("status", status)
                .andEqualTo("valid", true);
        return example;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void rejectEmpAppro(String empId, String type, TokenUser tokenUser) {
        // 根据审批类型查询查询条件
        Example example = buildExampleByApproType(empId, type);
        if (example == null) {
            return;
        }

        // 审批不成功
        EmpInfoDO empInfoUp = new EmpInfoDO();
        empInfoUp.setChangeStatus(0);
        empInfoUp.setApprovalStatus(ApprovalStatusEnum.APPRO_FAIL.getValue());
        // 修改
        empInfoDAO.updateByExampleSelective(empInfoUp, example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void confirmToJoin(EmpInfoUpdateDTO empInfoUpdateDTO, TokenUser tokenUser) {
        String empId = empInfoUpdateDTO.getId();
        // 校验
        EmpInfoDO empInfoDO = selectDOById(empId, tokenUser.getSiteId());
        if (Objects.isNull(empInfoDO)) {
            throw new ParamException("员工信息不正确或已删除");
        } else if (!empInfoDO.getStatus().equals(EmpInfoStatus.WAIT_ENTRY.getValue())) {
            throw new ParamException("员工已不是待入职状态,不需要确认到岗");
        } else if (!empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                && !empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_DISABLE.getValue())) {
            throw new ParamException("员工入职审批不通过,不能确认到岗");
        }

        // 确认到岗修改状态
        empInfoUpdateDTO.setId(empId);
        empInfoUpdateDTO.setStatus(HAS_ENTRY.getValue());
        empInfoUpdateDTO.setArrival(true);
        empInfoUpdateDTO.setApprovalStatus(ApprovalStatusEnum.APPRO_DISABLE.getValue());
        // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
        empInfoUpdateDTO.setChangeStatus(0);
        // 修改
        update(empInfoUpdateDTO, tokenUser);

        // 处理家庭成员+紧急联系人信息
        processFamilyAndContacts(empInfoUpdateDTO, tokenUser);

        // 保存自定义字段值
        saveAdditionalField(empInfoUpdateDTO.getAddEmpFieldList(), empInfoUpdateDTO.getCompanyId()
                , empInfoDO.getId(), tokenUser);
        // 发送入职通知
        sendNoticeTask.addTask(empInfoDO.getId(), NoticeConstants.INDUCTION, empInfoDO.getCompanyId(), DateUtil.offsetMinute(new Date(), 1), "人员入职发送通知", tokenUser);
        // 加入员工部门/岗位
        // 部门ID列表
        if (!StringUtils.isEmpty(empInfoDO.getPreJoinDep())) {
            String[] depIdList = empInfoDO.getPreJoinDep().split(",");
            publishEmpDep(Arrays.asList(depIdList), empInfoDO.getCompanyId(), empInfoDO.getId(), tokenUser);

        }
        // 岗位ID列表
        if (!StringUtils.isEmpty(empInfoDO.getPreJoinPosition())) {
            String[] positionIdList = empInfoDO.getPreJoinPosition().split(",");
            publishEmpPosition(Arrays.asList(positionIdList), empInfoDO.getCompanyId(), empInfoDO.getId(), tokenUser);

        }
        HrLogKit.logForSave("员工确认到岗,员工姓名:" + empInfoDO.getName(),
                "confirmToJoin", empInfoDO.getId(), empInfoDO.getCompanyId(), tokenUser);
        //记录人事变动表 办理入职
        personalEventService.autoSave(empInfoDO.to(EmpInfoVO.class), tokenUser, PersonalEventEnum.ENTRY.getDesc(), PersonalEventEnum.ENTRY.getValue(), PersonalEventEnum.ENTRY.getDesc());

    }

    @Override
    public List<EmpReduceInfoVO> listEmpReduceByDepIds(String companyId, String name, Boolean onlyUser, Boolean isOnlineOrLeave, TokenUser tokenUser, String... depIds) {
        if (depIds == null) {
            return new ArrayList<>();
        }
        // 公司全部员工信息及员工对应部门信息
        List<EmpReduceInfoVO> empReduceInfoList = listEmpReduceAndDepInfo(companyId, tokenUser.getSiteId());


        // 根据条件筛选
        EmpReduceQuery empReduceQuery = new EmpReduceQuery(name,
                onlyUser,
                isOnlineOrLeave,
                true,
                null);

        empReduceInfoList = filterByCondition(empReduceInfoList, companyId, empReduceQuery, tokenUser);
        if (CollectionUtils.isEmpty(empReduceInfoList)) {
            return new ArrayList<>();
        }
        // 筛选部门
        return empReduceInfoList.stream()
                .filter(empInfo -> Arrays.asList(depIds).contains(empInfo.getDepId()))
                .collect(Collectors.toList());
    }

    /**
     * 根据条件筛选员工信息
     *
     * @param empReduceInfoList 员工列表
     * @param companyId         公司id
     * @param tokenUser         当前用户
     */
    private List<EmpReduceInfoVO> filterByCondition(List<EmpReduceInfoVO> empReduceInfoList, String companyId, EmpReduceQuery empReduceQuery, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(empReduceInfoList)) {
            return new ArrayList<>();
        }
        // 当前用工单位是不是子公司下的
        boolean isChild = checkIsChildCompany(companyId, tokenUser);

        return empReduceInfoList.stream()
                .filter(empInfo -> {
                    // 姓名/手机号模糊查询
                    if (StringUtils.isNotEmpty(empReduceQuery.getEmpNameOrPhone())) {
                        if (empReduceQuery.getEmpNameOrPhone().contains(",")) {
                            // 根据多手机号匹配,158xxxxxxxx,158xxxxxxxx
                            if (!empReduceQuery.getEmpNameOrPhone().contains(empInfo.getPhone())) {
                                return false;
                            }
                        } else {
                            // // 姓名/手机号模糊查询
                            if (!empInfo.getName().contains(empReduceQuery.getEmpNameOrPhone())
                                    && !empInfo.getPhone().contains(empReduceQuery.getEmpNameOrPhone())) {
                                return false;
                            }
                        }
                    }

                    // 是否只展示有用户的员工
                    if (empReduceQuery.getOnlyUser() != null && empReduceQuery.getOnlyUser() && StringUtils.isEmpty(empInfo.getUserId())) {
                        return false;
                    }
                    // 是在职还是离职
                    if (empReduceQuery.getIsOnlineOrLeave() == null || empReduceQuery.getIsOnlineOrLeave()) {
                        // 员工状态入职或待离职
                        if (!empInfo.getStatus().equals(HAS_ENTRY.getValue())
                                && !empInfo.getStatus().equals(EmpInfoStatus.WAIT_QUIT.getValue())) {
                            return false;
                        }
                    } else {
                        if (!empInfo.getStatus().equals(EmpInfoStatus.HAS_QUIT.getValue())) {
                            return false;
                        }
                    }
                    // 所有条件都符合
                    return StringUtils.isNotEmpty(empInfo.getId());
                })
                .collect(Collectors.toList());
    }


    @Override
    public List<EmpReduceInfoVO> listEmpReduceByPositionIds(String companyId, TokenUser tokenUser, String... positionIds) {
        if (positionIds == null) {
            return new ArrayList<>();
        }
        // 公司全部员工信息及员工对应部门信息
        List<EmpReduceInfoVO> empReduceInfoList = listEmpReduceAndPositionInfo(companyId, tokenUser.getSiteId());

        // 根据条件筛选
        EmpReduceQuery empReduceQuery = new EmpReduceQuery(
                null,
                null,
                true,
                true,
                null);
        empReduceInfoList = filterByCondition(empReduceInfoList, companyId, empReduceQuery, tokenUser);
        if (CollectionUtils.isEmpty(empReduceInfoList)) {
            return new ArrayList<>();
        }
        // 筛选部门
        return empReduceInfoList.stream()
                .filter(empInfo -> Arrays.asList(positionIds).contains(empInfo.getPositionId()))
                .collect(Collectors.toList());
    }

    @Override
    public List<EmpInfoListVO> listAllVoByDepId(String companyId, String name, Boolean onlyUser, Boolean isOnlineOrLeave, TokenUser tokenUser, String... depIds) {
        List<EmpReduceInfoVO> empReduceList = listEmpReduceByDepIds(companyId, name, onlyUser, isOnlineOrLeave, tokenUser, depIds);
        if (!CollectionUtils.isEmpty(empReduceList)) {
            List<EmpInfoListVO> empInfoVoList = empReduceList.stream()
                    .map(empReduce -> empReduce.to(EmpInfoListVO.class))
                    .collect(Collectors.toList());
            // 增加部门和岗位信息
            addDepAndPositionToEmpList(empInfoVoList, companyId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empInfoVoList)) {
                // 去下重
                empInfoVoList = empInfoVoList.stream().distinct().collect(Collectors.toList());
            }
            return empInfoVoList;
        }
        return new ArrayList<>();
    }

    /**
     * 增加部门和岗位信息到员工信息列表
     *
     * @param empInfoList 员工信息列表
     * @param companyId   公司id
     * @param siteId      站点id
     */
    private void addDepAndPositionToEmpList(List<EmpInfoListVO> empInfoList, String companyId, String siteId) {
        if (CollectionUtils.isEmpty(empInfoList)) {
            return;
        }
        if (StringUtils.isEmpty(companyId)) {
            companyId = empInfoList.get(0).getCompanyId();
        }
        // 员工与部门的关系
        Map<String, List<EmpReduceInfoVO>> empDepMap = getEmpDepMap(companyId, siteId);

        // 员工与岗位的关系
        Map<String, List<EmpReduceInfoVO>> empPositionMap = getEmpPositionMap(companyId, siteId);


        empInfoList.forEach(
                empInfo -> {
                    // 部门
                    String depNames = getDepNameByEmpId(empInfo.getId(), empDepMap);
                    if (StringUtils.isEmpty(depNames)) {
                        empInfo.setDepName("暂无");
                    } else {
                        empInfo.setDepName(depNames);
                    }

                    // 岗位
                    String positionNames = getPositionNameByEmpId(empInfo.getId(), empPositionMap);
                    if (StringUtils.isEmpty(positionNames)) {
                        empInfo.setPositionName("暂无");
                    } else {
                        empInfo.setPositionName(positionNames);
                    }
                }
        );
    }

    /**
     * 获取员工的部门
     *
     * @param empId     员工id
     * @param empDepMap <empId,员工对应的部门>
     * @return 获取员工的部门
     */
    @Override
    public String getDepNameByEmpId(String empId, Map<String, List<EmpReduceInfoVO>> empDepMap) {
        if (empDepMap.containsKey(empId)) {
            List<EmpReduceInfoVO> empDepList = empDepMap.get(empId);

            List<String> nameList = empDepList.parallelStream()
                    .map(EmpReduceInfoVO::getDepName).distinct()
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(nameList)) {
                // 排序,统一下名称顺序
                Collections.sort(nameList);
                return String.join(",", nameList);
            }
        }
        return "";
    }

    /**
     * 获取员工的岗位
     *
     * @param empId          员工id
     * @param empPositionMap <empId,员工对应的岗位>
     * @return 获取员工的岗位
     */
    @Override
    public String getPositionNameByEmpId(String empId, Map<String, List<EmpReduceInfoVO>> empPositionMap) {
        if (empPositionMap.containsKey(empId)) {
            List<EmpReduceInfoVO> empPositionList = empPositionMap.get(empId);

            List<String> nameList = empPositionList.parallelStream()
                    .map(EmpReduceInfoVO::getPositionName).distinct()
                    .collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(nameList)) {
                // 排序,统一下名称顺序
                Collections.sort(nameList);
                return String.join(",", nameList);
            }
        }
        return "";
    }


    @Override
    public List<EmpInfoListVO> listAllVoByPositionId(String companyId, TokenUser tokenUser, String... positionIds) {
        List<EmpReduceInfoVO> empReduceList = listEmpReduceByPositionIds(companyId, tokenUser, positionIds);
        if (CollectionUtils.isEmpty(empReduceList)) {
            return new ArrayList<>();
        } else {
            List<EmpInfoListVO> empInfoVoList = empReduceList.stream()
                    .map(empReduce -> empReduce.to(EmpInfoListVO.class))
                    .collect(Collectors.toList());
            // 去下重
            return empInfoVoList.stream().distinct().collect(Collectors.toList());
        }
    }

    @Override
    public Page<EmpInfoListVO> pageEmpInfoByDepAndEmpInfo(DepAndInfoQuery depAndInfoQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", depAndInfoQuery.getCompanyId())
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());

        // 员工状态入职或待离职
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());

        // 员工姓名
        if (!StringUtils.isEmpty(depAndInfoQuery.getEmpNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + depAndInfoQuery.getEmpNameOrPhone() + "%")
                    .orLike("phone", "%" + depAndInfoQuery.getEmpNameOrPhone() + "%");
        }
        // 当前部门
        if (!StringUtils.isEmpty(depAndInfoQuery.getCurrentDepId())) {
            List<String> depIdList = new ArrayList<>();
            // 只显示当前部门
            if (depAndInfoQuery.getOnlyCurrentDep()) {
                depIdList.add(depAndInfoQuery.getCurrentDepId());
            } else {
                // 获取当前部门及子部门
                List<DepInfoDO> depInfoList = depInfoService.listAllAndChild(tokenUser.getSiteId(), depAndInfoQuery.getCurrentDepId());
                if (!CollectionUtils.isEmpty(depInfoList)) {
                    depIdList = depInfoList.stream().map(DepInfoDO::getId).collect(Collectors.toList());
                }
            }
            if (!CollectionUtils.isEmpty(depIdList)) {
                String[] depIds = depIdList.toArray(new String[depIdList.size()]);
                List<EmpDepDO> empDepList = empDepService.listAllByDepId(depAndInfoQuery.getCompanyId(), tokenUser.getSiteId(), depIds);
                if (CollectionUtils.isEmpty(empDepList)) {
                    // 部门下没有员工,直接返回
                    return null;
                }
                // 已加入部门的员工id
                List<String> joinDepEmpIdList = empDepList.stream().map(EmpDepDO::getEmpId).collect(Collectors.toList());
                example.and()
                        .andIn("id", joinDepEmpIdList);
            }
        }
        example.orderBy("gmtCreate").desc().orderBy("id").desc();

        return pageVoByExample(example, depAndInfoQuery.getCompanyId(), depAndInfoQuery.getPageNo(), depAndInfoQuery.getPageSize(), tokenUser.getSiteId());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void saveOnJobEmpInfo(EmpInfoOnJobDTO empInfoOnJobDTO, TokenUser tokenUser) {
        // 要入职的部门
        if (org.springframework.util.StringUtils.isEmpty(empInfoOnJobDTO.getPreJoinDep())) {
            if (!CollectionUtils.isEmpty(empInfoOnJobDTO.getDepIdList())) {
                String depIds = String.join(",", empInfoOnJobDTO.getDepIdList());
                empInfoOnJobDTO.setPreJoinDep(depIds);
            }
        }
        /* 要入职的岗位*/
        if (org.springframework.util.StringUtils.isEmpty(empInfoOnJobDTO.getPreJoinPosition())) {
            if (!CollectionUtils.isEmpty(empInfoOnJobDTO.getDepIdList())) {
                String positionIds = String.join(",", empInfoOnJobDTO.getPositionIdList());
                empInfoOnJobDTO.setPreJoinPosition(positionIds);
            }
        }
        PersonalEventDO personalEventDO = new PersonalEventDO();
        EmpInfoVO empInfoVO = new EmpInfoVO();
        // 校验入职审批流程
        List<ApproFlowListVO> approFlowList = approProviderService.listOnJobCanUseFlowsByCompany(empInfoOnJobDTO.getCompanyId(), tokenUser);
        StringBuilder desc = new StringBuilder();
        desc.append(PersonalEventExample.INSERT_INTO_ADMIN + tokenUser.getUserName());
        desc.append(PersonalEventEnum.ENTRY_PROCEDURE.getDesc() + ",");
        if (CollectionUtils.isEmpty(approFlowList)) {
            // 无可用的入职审批流程,直接入职完成
            // 待入职
            empInfoOnJobDTO.setStatus(WAIT_ENTRY.getValue());
            // 不需要审批
            empInfoOnJobDTO.setApprovalStatus(ApprovalStatusEnum.APPRO_DISABLE.getValue());
            // 保存员工信息
            empInfoVO = saveEmpInfoPre(empInfoOnJobDTO, tokenUser);
            personalEventDO.setEmpId(empInfoVO.getId());
            desc.append(PersonalEventExample.INSERT_NO_DP + ",");
        } else {
            String approFlowId = empInfoOnJobDTO.getApproFlowId();
            if (org.springframework.util.StringUtils.isEmpty(approFlowId)) {
                if (approFlowList.size() > 1) {
                    throw new ParamException("请先选择合适的入职审批流程再办理入职");
                } else {
                    approFlowId = approFlowList.get(0).getId();
                }
            }
            // 待入职
            empInfoOnJobDTO.setStatus(WAIT_ENTRY.getValue());
            // 待审批
            empInfoOnJobDTO.setApprovalStatus(ApprovalStatusEnum.APPRO_PRE.getValue());
            // 保存员工信息
            empInfoVO = saveEmpInfoPre(empInfoOnJobDTO, tokenUser);
            personalEventDO.setEmpId(empInfoVO.getId());
            String jobType = "1".equals(empInfoVO.getEmployType()) ? "非正式" : "正式";
            //拼接办理入职事件详情
            desc.append(PersonalEventExample.INSERT_POSITION + listPositionNameByEmp(empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser.getSiteId()));
            desc.append(PersonalEventExample.INSERT_DEPT + listDepNameByEmp(empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser.getSiteId()) + "，");
            desc.append(PersonalEventExample.INSERT_TYPE + jobType + "，");

            personalEventDO.setDescription(desc.toString());

            // 发起入职审批
            approProviderService.createOnJobAppro(empInfoVO, approFlowId, tokenUser);
        }
        desc.append(PersonalEventExample.INSERT_PREJOIN_TIME + empInfoVO.getPreJoinDate());
        personalEventService.autoSave(empInfoVO, tokenUser, desc.toString(), PersonalEventEnum.ENTRY_PROCEDURE.getValue(), PersonalEventEnum.ENTRY_PROCEDURE.getDesc());

    }

    /**
     * 发布关联信息
     *
     * @param empAllInfoDTO 关联信息
     * @param empInfoVO     用户信息
     * @param tokenUser     当前用户
     */
    private void publishEmpRelation(EmpAllInfoDTO empAllInfoDTO, EmpInfoVO empInfoVO, TokenUser tokenUser) {
        // 员工家庭成员
        publishEmpFamilyList(empAllInfoDTO.getEmpFamilyList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工奖惩记录
        publishEmpRewardPunishList(empAllInfoDTO.getEmpRewardPunishList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

//        // 员工档案信息
//        publishEmpArchivesList(empAllInfoDTO.getEmpArchivesList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工工作经历
        publishEmpWorkList(empAllInfoDTO.getEmpWorkList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工合同
        publishEmpContractList(empAllInfoDTO.getEmpContractList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工联系人
        publishEmpContactsList(empAllInfoDTO.getEmpContactsList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工教育经历
        publishEmpEducationList(empAllInfoDTO.getEmpEducationList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工证件信息
        publishEmpCardList(empAllInfoDTO.getEmpCardList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工培训记录
        publishEmpTrainList(empAllInfoDTO.getEmpTrainList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 员工证书
        publishEmpCertificateList(empAllInfoDTO.getEmpCertificateList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 部门ID列表
        publishEmpDep(empAllInfoDTO.getDepIdList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 岗位ID列表
        publishEmpPosition(empAllInfoDTO.getPositionIdList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);

        // 纸质合同
        publishEmpPaperContractList(empAllInfoDTO.getEmpPaperContractList(), empInfoVO.getCompanyId(), empInfoVO.getId(), tokenUser);
    }

    /**
     * 员工部门
     *
     * @param depIdList 部门id集合
     * @param companyId 公司id
     * @param empId     员工id
     * @param tokenUser 当前用户
     */
    private void publishEmpDep(List<String> depIdList, String companyId, String empId, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(depIdList)) {
            return;
        }
        List<EmpDepAddDTO> empDepAddList = new ArrayList<>();
        List<DepInfoDO> depInfoDOList = depInfoService.selectByIds(depIdList, tokenUser);
        depInfoDOList.forEach(depInfoDO -> {
            EmpDepAddDTO empDepAddDTO = new EmpDepAddDTO();
            empDepAddDTO.setDepId(depInfoDO.getId());
            empDepAddDTO.setEmpId(empId);
            empDepAddDTO.setCompanyId(companyId);
            empDepAddList.add(empDepAddDTO);
        });
        if (!CollectionUtils.isEmpty(empDepAddList)) {
            empDepService.publishEmpDepList(empDepAddList, tokenUser);
        }
    }

    /**
     * 员工岗位
     *
     * @param positionIdList 岗位ID列表
     * @param companyId      公司id
     * @param empId          员工id
     * @param tokenUser      当前用户
     */
    private void publishEmpPosition(List<String> positionIdList, String companyId, String empId, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(positionIdList)) {
            return;
        }
        List<EmpPositionAddDTO> empPositionAddList = new ArrayList<>();
        positionIdList.forEach(
                positionId -> {
                    PositionInfoVO positionInfo = positionInfoService.selectById(positionId, tokenUser.getSiteId());
                    if (!Objects.isNull(positionInfo)) {
                        EmpPositionAddDTO empPositionAddDTO = new EmpPositionAddDTO();
                        empPositionAddDTO.setPositionId(positionId);
                        empPositionAddDTO.setEmpId(empId);
                        empPositionAddDTO.setCompanyId(companyId);
                        empPositionAddList.add(empPositionAddDTO);
                    }
                }
        );
        if (!CollectionUtils.isEmpty(empPositionAddList)) {
            empPositionService.publishEmpPositionList(empPositionAddList, tokenUser);
        }
    }


    /**
     * 员工家庭成员
     *
     * @param empFamilyList 家庭成员
     * @param tokenUser     当前用户
     */
    private void publishEmpFamilyList(List<EmpFamilyDTO> empFamilyList, String companyId, String empId, TokenUser tokenUser) {
        if (empFamilyList == null) {
            return;
        }
        // 发布
        empFamilyService.publishEmpFamilyList(empFamilyList, companyId, empId, tokenUser);
    }


    /**
     * 员工奖惩记录
     *
     * @param empRewardPunishList 奖惩记录
     * @param tokenUser           当前用户
     */
    private void publishEmpRewardPunishList(List<EmpRewardPunishDTO> empRewardPunishList, String companyId, String empId, TokenUser tokenUser) {
        if (empRewardPunishList == null) {
            return;
        }
        // 发布
        empRewardPunishService.publishEmpRewardPunishList(empRewardPunishList, companyId, empId, tokenUser);
    }


//    /**
//     * 员工档案
//     *
//     * @param empArchivesList 档案
//     * @param tokenUser       当前用户
//     */
//    private void publishEmpArchivesList(List<EmpArchivesDTO> empArchivesList, String companyId, String empId, TokenUser tokenUser) {
//        if (empArchivesList == null) {
//            return;
//        }
//        // 发布
//        empArchivesService.publishEmpArchivesList(empArchivesList, companyId, empId, tokenUser);
//    }


    /**
     * 员工工作经历
     *
     * @param empWorkList 工作经历
     * @param tokenUser   当前用户
     */
    private void publishEmpWorkList(List<EmpWorkDTO> empWorkList, String companyId, String empId, TokenUser tokenUser) {
        if (empWorkList == null) {
            return;
        }
        // 发布
        empWorkService.publishEmpWorkList(empWorkList, companyId, empId, tokenUser);
    }

    /**
     * 员工联系人
     *
     * @param empContactsList 员工联系人
     * @param tokenUser       当前用户
     */
    private void publishEmpContactsList(List<EmpContactsDTO> empContactsList, String companyId, String empId, TokenUser tokenUser) {
        if (empContactsList == null) {
            return;
        }
        // 发布
        empContactsService.publishEmpContactsList(empContactsList, companyId, empId, tokenUser);
    }

    /**
     * 员工合同
     *
     * @param empContractList 员工合同
     * @param tokenUser       当前用户
     */
    private void publishEmpContractList(List<EmpContractDTO> empContractList, String companyId, String empId, TokenUser tokenUser) {
        if (empContractList == null) {
            return;
        }
        // 发布
        empContractService.publishEmpContractList(empContractList, companyId, empId, tokenUser);
    }

    /**
     * 员工教育经历
     *
     * @param empEducationList 员工教育经历
     * @param tokenUser        当前用户
     */
    private void publishEmpEducationList(List<EmpEducationDTO> empEducationList, String companyId, String empId, TokenUser tokenUser) {
        if (empEducationList == null) {
            return;
        }
        // 发布
        empEducationService.publishEmpEducationList(empEducationList, companyId, empId, tokenUser);
    }

    /**
     * 员工证件信息
     *
     * @param empCardList 员工证件信息
     * @param tokenUser   当前用户
     */
    private void publishEmpCardList(List<EmpCardDTO> empCardList, String companyId, String empId, TokenUser tokenUser) {
        if (empCardList == null) {
            return;
        }
        // 发布
        empCardService.publishEmpCardList(empCardList, companyId, empId, tokenUser);
    }

    /**
     * 员工培训记录
     *
     * @param empTrainList 员工培训记录
     * @param tokenUser    当前用户
     */
    private void publishEmpTrainList(List<EmpTrainDTO> empTrainList, String companyId, String empId, TokenUser tokenUser) {
        if (empTrainList == null) {
            return;
        }
        // 发布
        empTrainService.publishEmpTrainList(empTrainList, companyId, empId, tokenUser);
    }

    /**
     * 员工证书
     *
     * @param empCertificateList 员工证书
     * @param tokenUser          当前用户
     */
    private void publishEmpCertificateList(List<EmpCertificateDTO> empCertificateList, String companyId, String empId, TokenUser tokenUser) {
        if (empCertificateList == null) {
            return;
        }
        // 发布
        empCertificateService.publishEmpCertificateList(empCertificateList, companyId, empId, tokenUser);
    }

    /**
     * 纸质合同
     *
     * @param empPaperContractList 纸质合同
     * @param tokenUser            当前用户
     */
    private void publishEmpPaperContractList(List<EmpPaperContractDTO> empPaperContractList, String companyId, String empId, TokenUser tokenUser) {
        if (empPaperContractList == null) {
            return;
        }
        // 发布
        empPaperContractService.publishEmpPaperContractList(empPaperContractList, companyId, empId, tokenUser);
    }

    @Override
    public List<EmpInfoDO> listTurnStraightTaskToday() {
        // 获取明天时间0点
        Date dateTomorrow = DateUtils.getTomorrow();

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("status", HAS_ENTRY.getValue())
                // 正式类型（1：试用期，2：已转正）
                .andEqualTo("formalType", 1)
                // 转正时间在明天之前
                .andLessThan("turnStraightDate", dateTomorrow)
                .andEqualTo("valid", true);

        // 审批通过或不需要审批
        example.and()
                .orEqualTo("approvalStatus", ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                .orEqualTo("approvalStatus", ApprovalStatusEnum.APPRO_DISABLE.getValue());

        example.orderBy("gmtCreate").desc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listBeFormalTask() {
        List<EmpInfoDO> empInfoDOS = empInfoDAO.listBeFormalTask();
        EmpInfoDO empInfoDO = null;
        Date retirementDate = null;
        Iterator<EmpInfoDO> iterator = empInfoDOS.iterator();
        while (iterator.hasNext()) {
            empInfoDO = iterator.next();
            if (empInfoDO.getRetirementAge() == null && empInfoDO.getRetirementDate() == null) {
                iterator.remove();
            } else if (empInfoDO.getRetirementAge() != null && empInfoDO.getRetirementDate() == null) {
                //现在时间到退休时间小于365天
                if (StringUtils.isEmpty(empInfoDO.getBirthday())) {
                    iterator.remove();
                } else {
                    Date birthdayDate = DateUtil.parse(empInfoDO.getBirthday());
                    retirementDate = DateUtil.offset(birthdayDate, DateField.YEAR, empInfoDO.getRetirementAge());
                    long diff = retirementDate.getTime() - new Date().getTime();
                    int day = (int) (diff / DateUnit.DAY.getMillis());
                    if (day < 365 && day >= 0) {
                        empInfoDO.setRetirementDate(retirementDate);
                    } else {
                        iterator.remove();
                    }
                }
            } else if (empInfoDO.getRetirementAge() == null && empInfoDO.getRetirementDate() != null) {
                if (empInfoDO.getRetirementDate().before(DateUtil.beginOfDay(new Date()))) {
                    iterator.remove();
                }
            }
        }
        return empInfoDOS;
    }

    @Override
    public List<EmpInfoDO> listTurnOfficialTask() {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("status", HAS_ENTRY.getValue())
                // 正式类型（1：试用期，2：已转正）
                .andEqualTo("formalType", 1)
                .andEqualTo("valid", true);
        example.orderBy("companyId");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listResignTask() {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("status", WAIT_QUIT.getValue())
                .andEqualTo("valid", true);
        example.orderBy("companyId");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listInductionTask() {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("status", WAIT_ENTRY.getValue())
                .andEqualTo("valid", true);
        example.and()
                .andNotEqualTo("arrival", false)
                .orIsNull("arrival");
        example.orderBy("companyId");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> listTransferTask() {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("status", Arrays.asList(WAIT_QUIT.getValue(), HAS_ENTRY.getValue()))
                // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
                .andEqualTo("changeStatus", 2)
                .andEqualTo("valid", true);
        example.orderBy("companyId");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void updateEmpUnionId(String empId, String unionId) {
        EmpInfoDO empInfoUp = new EmpInfoDO();
        empInfoUp.setId(empId);
        empInfoUp.setUnionId(unionId);

        empInfoDAO.updateByPrimaryKeySelective(empInfoUp);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO saveExcelDataList(List<EmpInfoImportDTO> list, Boolean isAdd, TokenUser tokenUser, String companyId) {
        List<AreaReduceVO> areaList = adminProviderService.listAllArea();
        ParamException.notEmpty(list, "没有需要导入的数据");
        EmpImportExcelVO empImportExcelVO = new EmpImportExcelVO();
        //成功导入列表
        List<EmpInfoImportDTO> importSucList = new ArrayList<>();
        //失败导入列表
        List<EmpInfoImportDTO> importFailList = new ArrayList<>();
        // 新增的员工
        List<EmpInfoDO> empInfoAddList = new ArrayList<>();
        // 修改的员工
        List<EmpInfoDO> empInfoUpdateList = new ArrayList<>();

        //  站点下所有在职员工
        List<EmpReduceInfoVO> empReduceList = empInfoDAO.listOnJobEmpReduceBySite(tokenUser.getSiteId());
        // map<手机号,此手机号对应的员工>
        Map<String, List<EmpReduceInfoVO>> empPhoneMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empReduceList)) {
            if (isAdd) {
                empPhoneMap = empReduceList.parallelStream().collect(
                        Collectors.groupingBy(EmpReduceInfoVO::getPhone));
            } else {
                empPhoneMap = empReduceList.parallelStream()
                        .filter(s -> EmpInfoStatus.HAS_ENTRY.getValue().equals(s.getStatus())
                                || WAIT_QUIT.getValue().equals(s.getStatus()))
                        .collect(Collectors.groupingBy(EmpReduceInfoVO::getPhone));
            }
        }
        // map<身份证号,此身份证号对应的员工>
        Map<String, List<EmpReduceInfoVO>> empIdCardMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empReduceList)) {
            if (isAdd) {
                empIdCardMap = empReduceList.parallelStream()
                        .filter(s -> StrKit.isNotEmpty(s.getIdCard())).collect(
                                Collectors.groupingBy(EmpReduceInfoVO::getIdCard));
            } else {
                empIdCardMap = empReduceList.parallelStream()
                        .filter(s -> StrKit.isNotEmpty(s.getIdCard())
                                && (EmpInfoStatus.HAS_ENTRY.getValue().equals(s.getStatus())
                                || WAIT_QUIT.getValue().equals(s.getStatus()))).collect(
                                Collectors.groupingBy(EmpReduceInfoVO::getIdCard));
            }

        }
        // excel中重复手机号
        Map<String, List<EmpInfoImportDTO>> phoneImportMap = list.parallelStream()
                .filter(empInfo -> StringUtils.isNotEmpty(empInfo.getPhone()))
                .collect(Collectors.groupingBy(EmpInfoImportDTO::getPhone));

        // excel中重复身份证号
        Map<String, List<EmpInfoImportDTO>> icCardImportMap = list.parallelStream()
                .filter(empInfo -> StringUtils.isNotEmpty(empInfo.getIdCard()))
                .collect(Collectors.groupingBy(EmpInfoImportDTO::getIdCard));

        // 处理导入数据
        log.info("花名册导入数据,循环处理导入数据开始,时间戳:{}", System.currentTimeMillis());
        List<String> channelNameList = list.stream()
                .map(EmpInfoImportDTO::getChannelName).distinct().collect(Collectors.toList());
        channelNameList.removeIf(Objects::isNull);
        List<ChannelDO> channelList = channelService.selectByNameList(channelNameList, tokenUser.getSiteId());
        Map<String, ChannelDO> channelMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(channelList)) {
            channelMap = channelList.stream().collect(Collectors.toMap(ChannelDO::getName, v -> v));
        }
        List<String> importPhoneList = list.stream()
                .map(EmpInfoImportDTO::getPhone).distinct().collect(Collectors.toList());
        importPhoneList.removeIf(Objects::isNull);
        List<CheckInPeopleDO> checkInPeopleList = checkInPeopleService.selectByPhoneList(importPhoneList, tokenUser.getSiteId());
        Map<String, CheckInPeopleDO> checkInPeopleMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(checkInPeopleList)) {
            checkInPeopleMap = checkInPeopleList.stream().collect(Collectors.toMap(CheckInPeopleDO::getPhone, v -> v));
        }
        for (int i = 0; i < list.size(); i++) {
            EmpInfoImportDTO empInfoImportDTO = list.get(i);

            empInfoImportDTO.setJoinDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setJoinWorkDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setTurnStraightDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setContractStartDateStr(DateKit8.format2Date(empInfoImportDTO.getContractEndDate()));
            empInfoImportDTO.setContractEndDateStr(DateKit8.format2Date(empInfoImportDTO.getContractStartDate()));

            if (empInfoImportDTO.getReason() != null) {
                importFailList.add(empInfoImportDTO);
                continue;
            }
            //  姓名不能为空
            if (StrKit.isEmpty(empInfoImportDTO.getName()) && isAdd) {
                empInfoImportDTO.setReason("员工姓名：为空");
                empInfoImportDTO.setField("name");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 身份证不能为空
            String idCard = empInfoImportDTO.getIdCard();
            if (StrKit.isEmpty(idCard)) {
                empInfoImportDTO.setReason("身份证号：为空");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 手机号不能为空
            if (StrKit.isEmpty(empInfoImportDTO.getPhone()) && isAdd) {
                empInfoImportDTO.setReason("手机号：为空");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 邮箱格式校验
            if (StrKit.isNotEmpty(empInfoImportDTO.getEmail()) && !RegUtils.isEmail(empInfoImportDTO.getEmail())) {
                empInfoImportDTO.setReason("个人邮箱：格式有误，请参考模板");
                empInfoImportDTO.setField("email");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 工作性质不能为空
            if (Objects.isNull(empInfoImportDTO.getPostType()) && isAdd) {
                empInfoImportDTO.setReason("工作性质：为空");
                empInfoImportDTO.setField("postType");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 入职时间不能为空
            if (Objects.isNull(empInfoImportDTO.getJoinDate()) && isAdd) {
                empInfoImportDTO.setReason("入职时间：为空");
                empInfoImportDTO.setField("joinDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 退休年龄格式
            if (!Objects.isNull(empInfoImportDTO.getRetirementAge())) {
                if (empInfoImportDTO.getRetirementAge() <= 0) {
                    empInfoImportDTO.setReason("退休年龄：非正整数");
                    empInfoImportDTO.setField("retirementAge");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            if (!Objects.isNull(empInfoImportDTO.getAllMap())) {
                Map<String, String> allMap = empInfoImportDTO.getAllMap();
                // 养老保险格式
                String pf1 = allMap.get("养老保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 失业保险格式
                pf1 = allMap.get("失业保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 工伤保险格式
                pf1 = allMap.get("工伤保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 医疗保险格式
                pf1 = allMap.get("医疗保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 生育保险格式
                pf1 = allMap.get("生育保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 公积金格式
                pf1 = allMap.get("公积金");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 公积金比例格式
                pf1 = allMap.get("公积金比例");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1) && Double.parseDouble(pf1) >= 5 && Double.parseDouble(pf1) <= 12) {
                        String[] split = pf1.split("\\.");
                        if (split.length == 2 && split[1].length() > 2) {
                            empInfoImportDTO.setReason("公积金比例：格式有误；输入范围5-12，最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("公积金比例：格式有误；输入范围5-12，最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 起缴时间格式
                pf1 = allMap.get("起缴时间");
                if (!StringUtils.isEmpty(pf1)) {
                    String[] split1 = pf1.split("-");
                    if (split1.length != 2) {
                        String[] split2 = pf1.split("/");
                        if (split2.length != 2) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        } else {
                            if (!Validator.isNumber(split2[1]) || Integer.parseInt(split2[1]) > 12) {
                                empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        }
                    } else {
                        if (!Validator.isNumber(split1[1]) || Integer.parseInt(split1[1]) > 12) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    }
                    try {
                        DateUtil.parse(pf1, "yyyy-MM");
                    } catch (Exception e) {
                        try {
                            DateUtil.parse(pf1, "yyyy/MM");
                        } catch (Exception exception) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    }
                    String[] split = null;
                    if (pf1.contains("/")) {
                        split = pf1.split("/");
                    } else if (pf1.contains("-")) {
                        split = pf1.split("-");
                    }
                    if (split.length != 2) {
                        empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }

                }
                //参保城市格式
                pf1 = allMap.get("参保城市");
                if (!StringUtils.isEmpty(pf1)) {
                    String reback = FormatUtils.checkCity(pf1, areaList);
                    if (StringUtils.isEmpty(reback)) {
                        empInfoImportDTO.setReason("缴纳地址：格式有误，请参考模板");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    } else {
                        allMap.put("参保城市", pf1);
                    }
                }
            }
            // 身份证号格式
            if (!RegUtils.isIdCardAllType(idCard.toUpperCase())) {
                empInfoImportDTO.setReason("身份证号：格式有误");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验手机号是否在本公司的离职列表
            if (StrKit.isNotEmpty(empInfoImportDTO.getPhone())
                    && hasEmpResignByPhone(companyId, empInfoImportDTO.getPhone(), tokenUser)) {
                empInfoImportDTO.setReason("手机号：员工已存在于该用工单位的已离职列表，请直接为其更换用工单位");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验身份证是否在本公司的离职列表
            if (StrKit.isNotEmpty(empInfoImportDTO.getPhone())
                    && hasEmpResignByIdCard(companyId, idCard, tokenUser)) {
                empInfoImportDTO.setReason("身份证号：员工已存在于该用工单位的已离职列表，请直接为其更换用工单位");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验证件类型
            Integer cardType = RegUtils.cardType(idCard);
            empInfoImportDTO.setCertificateType(cardType);
            // 校验员工合同期限
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() == null) {
                if (empInfoImportDTO.getProbationDays() != null) {
                    // 试用期不为空 转正日期 = 入职日期 + 试用期
                    empInfoImportDTO.setTurnStraightDate(DateKit8.addDays(empInfoImportDTO.getJoinDate()
                            , empInfoImportDTO.getProbationDays()));
                } else {
                    // 试用期为空 转正日期 = 入职日期
                    empInfoImportDTO.setTurnStraightDate(empInfoImportDTO.getJoinDate());
                }
            }

            // 转正日期不能早于入职日期
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() != null
                    && empInfoImportDTO.getJoinDate().getTime() > empInfoImportDTO.getTurnStraightDate().getTime()) {
                // 已入职其他公司
                empInfoImportDTO.setReason("转正日期：转正日期需大于等于入职日期");
                empInfoImportDTO.setField("turnStraightDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }

            if (!org.springframework.util.StringUtils.isEmpty(empInfoImportDTO.getBirthday())) {
                String stringBuilder = empInfoImportDTO.getBirthday() + " " +
                        "00:00:00";
                empInfoImportDTO.setBirthday(stringBuilder);
            }
            // 转正日期大于现在是试用期
            if (Objects.isNull(empInfoImportDTO.getFormalType()) && Objects.nonNull(empInfoImportDTO.getTurnStraightDate())) {
                empInfoImportDTO.setFormalType(empInfoImportDTO.getTurnStraightDate().getTime()
                        > System.currentTimeMillis() ? 1 : 2);
            }

            // 手机号格式
            if (!RegUtils.isMobile(empInfoImportDTO.getPhone()) && isAdd) {
                // 手机号格式
                empInfoImportDTO.setReason("手机号：格式有误");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 重复手机号
            if (phoneImportMap.containsKey(empInfoImportDTO.getPhone())) {
                List<EmpInfoImportDTO> phoneList = phoneImportMap.get(empInfoImportDTO.getPhone());
                if (!CollectionUtils.isEmpty(phoneList) && phoneList.size() > 1) {
                    empInfoImportDTO.setReason("手机号：已存在");
                    empInfoImportDTO.setField("phone");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            // 重复身份证号
            if (icCardImportMap.containsKey(idCard)) {
                List<EmpInfoImportDTO> idCardList = icCardImportMap.get(idCard);
                if (!CollectionUtils.isEmpty(idCardList) && idCardList.size() > 1) {
                    empInfoImportDTO.setReason("身份证号：已存在");
                    empInfoImportDTO.setField("idCard");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            // 员工转正时间不能早于入职时间
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() != null
                    && empInfoImportDTO.getTurnStraightDate().before(empInfoImportDTO.getJoinDate())) {
                empInfoImportDTO.setReason("员工转正时间不能早于入职时间");
                empInfoImportDTO.setField("turnStraightDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 学历校验
            if (StrKit.isNotEmpty(empInfoImportDTO.getEducation())) {
                EducationLevelEnum byDesc = EducationLevelEnum.findByDesc(empInfoImportDTO.getEducation());
                if (Objects.isNull(byDesc)) {
                    empInfoImportDTO.setReason("学历：请填写系统数据");
                    empInfoImportDTO.setField("education");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }

            // 渠道
            if (StringUtils.isNotBlank(empInfoImportDTO.getChannelName())) {
                ChannelDO channelDO = channelMap.get(empInfoImportDTO.getChannelName());
                if (Objects.isNull(channelDO)) {
                    empInfoImportDTO.setReason("渠道来源：系统中无此渠道来源");
                    empInfoImportDTO.setField("channelName");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }


                // 保存渠道信息
                empInfoImportDTO.setChannelId(channelDO.getId());
                CheckInPeopleDO checkInPeopleDO = checkInPeopleMap.get(empInfoImportDTO.getPhone());
                if (Objects.nonNull(checkInPeopleDO)) {
                    CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                    checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                    checkInPeopleUpdateDTO.setChannelId(channelDO.getId());
                    checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
                } else {
                    // 新建预登记人员（来源为花名册）
                    CheckInPeopleAddDTO checkInPeopleAddDTO = new CheckInPeopleAddDTO();
                    checkInPeopleAddDTO.setName(empInfoImportDTO.getName());
                    checkInPeopleAddDTO.setPhone(empInfoImportDTO.getPhone());
                    checkInPeopleAddDTO.setIdcard(idCard);
                    checkInPeopleAddDTO.setChannelId(channelDO.getId());
                    checkInPeopleAddDTO.setSource(HrConstants.HUW);
                    checkInPeopleAddDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
                    checkInPeopleAddDTO.setWorkStatus(CheckInPeopleConstant.WORK_STATUS_RNTRY);
                    checkInPeopleService.save(checkInPeopleAddDTO, tokenUser);
                }
            }
            if (StrKit.isNotEmpty(empInfoImportDTO.getTag())) {
                String tag = empInfoImportDTO.getTag();
                // 将中文逗号替换为英文逗号
                tag = tag.replaceAll("，", ",");
                // 只有逗号不作为标签写入
                if (!",".equals(tag)) {
                    String[] array = tag.split(",");
                    List<String> tagList = Arrays.asList(array);
                    if (tagList.size() > MAX_TAG_COUNT) {
                        empInfoImportDTO.setReason("员工最多添加" + MAX_TAG_COUNT + "个标签");
                        empInfoImportDTO.setField("tag");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                    for (String tagItem : tagList) {
                        // 更新标签库
                        empTagService.saveTagByCompanyId(companyId, tagItem, tokenUser);
                    }
                    empInfoImportDTO.setTag(tag);
                }
            }

            // 校验员工合同期限
            if (StringUtils.isNotBlank(empInfoImportDTO.getContractExpireStr())) {
                try {
                    int parseInt;
                    if (empInfoImportDTO.getContractExpireStr().contains("年")) {
                        parseInt = Integer.parseInt(empInfoImportDTO.getContractExpireStr().replace("年", ""));
                        // 结束日期计算补全
                        if (empInfoImportDTO.getContractEndDate() == null && empInfoImportDTO.getContractStartDate() != null) {
                            Date date = DateKit8.addMonths(empInfoImportDTO.getContractStartDate(), parseInt * 12L);
                            empInfoImportDTO.setContractEndDate(DateKit8.addDays(date, -1));
                        }
                    } else if (empInfoImportDTO.getContractExpireStr().contains("月")) {
                        parseInt = Integer.parseInt(empInfoImportDTO.getContractExpireStr().replace("月", ""));
                        // 结束日期计算补全
                        if (empInfoImportDTO.getContractEndDate() == null && empInfoImportDTO.getContractStartDate() != null) {
                            Date date = DateKit8.addMonths(empInfoImportDTO.getContractStartDate(), parseInt);
                            empInfoImportDTO.setContractEndDate(DateKit8.addDays(date, -1));
                        }
                    } else {
                        // 合同期限：格式有误
                        empInfoImportDTO.setReason("合同期限：格式有误");
                        empInfoImportDTO.setField("timeLimit");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                    if (parseInt < 0 || parseInt > 10) {
                        // 合同期限：格式有误
                        empInfoImportDTO.setReason("合同期限：格式有误");
                        empInfoImportDTO.setField("timeLimit");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                } catch (NumberFormatException e) {
                    // 合同期限：格式有误
                    empInfoImportDTO.setReason("合同期限：格式有误");
                    empInfoImportDTO.setField("timeLimit");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }

            // 合同结束日期不能早于开始日期
            if (empInfoImportDTO.getContractStartDate() != null && empInfoImportDTO.getContractEndDate() != null
                    && empInfoImportDTO.getContractStartDate().getTime() > empInfoImportDTO.getContractEndDate().getTime()) {
                // 已入职其他公司
                empInfoImportDTO.setReason("合同结束时间：合同结束时间需大于等于合同开始时间");
                empInfoImportDTO.setField("contractEndDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 根据合同开始时间和结束时间 计算合同状态
            if (empInfoImportDTO.getContractStartDate() != null && empInfoImportDTO.getContractEndDate() != null) {
                long newDate = System.currentTimeMillis();
                Integer contractStatus;
                if (newDate < empInfoImportDTO.getContractStartDate().getTime()) {
                    contractStatus = ContractStatusEnum.NOT_STARTED.getValue();
                } else if (newDate > empInfoImportDTO.getContractEndDate().getTime()) {
                    contractStatus = ContractStatusEnum.EXPIRE.getValue();
                } else {
                    contractStatus = ContractStatusEnum.IMPLEMENT.getValue();
                }
                empInfoImportDTO.setContractsStatus(contractStatus);
            }
            // 合同类型校验
            if (StringUtils.isNotBlank(empInfoImportDTO.getContractType())) {
                //合同类型
                FileType fileType = FileType.findByDesc(empInfoImportDTO.getContractType());
                if (fileType == null) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("合同类型：格式有误");
                    empInfoImportDTO.setField("contractType");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                empInfoImportDTO.setFileTypeValue(fileType.getValue());
            }
            // 身份证号在租户的员工
            List<EmpReduceInfoVO> empReduceInfoVOList = empIdCardMap.get(idCard);
            // 身份证号在用工单位的员工
            if (!CollectionUtils.isEmpty(empReduceInfoVOList)) {
                empReduceInfoVOList = empReduceInfoVOList.parallelStream().filter(empReduceInfoVO
                        -> companyId.equals(empReduceInfoVO.getCompanyId())).collect(Collectors.toList());
            }
            ///////////////////////////////// 新增操作 /////////////////////////////////
            if (isAdd) {
                // 新增时需要满足：
                // 1、手机号不能在租户存在
                if (empPhoneMap.containsKey(empInfoImportDTO.getPhone())) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("手机号：手机号已有员工信息");
                    empInfoImportDTO.setField("phone");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                // 2、用工单位下不能有同身份证的
                if (!CollectionUtils.isEmpty(empReduceInfoVOList)) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("身份证号：身份证号已存在");
                    empInfoImportDTO.setField("idCard");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                // 尚未入职,新增
                EmpInfoDO empInfoAdd = empInfoImportDTO.to(EmpInfoDO.class);
                empInfoAdd.setSalaryType(SalaryFileTypeEnum.NO_SALARY.getValue());
                empInfoAddList.add(empInfoAdd);
                importSucList.add(empInfoImportDTO);
                continue;
            }
            ///////////////////////////////// 更新操作 /////////////////////////////////
            // 修改时需要满足：身份证需要在用工单位存在
            if (CollectionUtils.isEmpty(empReduceInfoVOList)) {
                // 身份证不在用工单位存在
                empInfoImportDTO.setReason("身份证号：此员工不是该用工单位的在职员工，请验证后重新导入");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            EmpReduceInfoVO empReduceInfoVO = empReduceInfoVOList.get(0);
            // 更新
            EmpInfoDO empInfoUp = empInfoImportDTO.to(EmpInfoDO.class);
            empInfoUp.setId(empReduceInfoVO.getId());
            //放入手机号后面同步预登记数据用
            empInfoUp.setPhone(empReduceInfoVO.getPhone());
            // 写入userId，后面发通知要用
            empInfoUp.setUserId(empReduceInfoVO.getUserId());
            empInfoUpdateList.add(empInfoUp);
            importSucList.add(empInfoImportDTO);
        }
        log.info("花名册导入数据,循环处理导入数据结束,时间戳:{}", System.currentTimeMillis());
        // 信息补全,一些员工默认的信息,信息处理,处理完成后进行保存
        empInfoComplementAndSave(empInfoUpdateList, false, companyId, tokenUser);
        empInfoComplementAndSave(empInfoAddList, true, companyId, tokenUser);
        if (!CollectionUtils.isEmpty(importSucList)) {
            //拿到保存成功的数据EmpId
            List<String> idCardList = importSucList.stream()
                    .map(EmpInfoImportDTO::getIdCard).collect(Collectors.toList());
            idCardList.removeIf(Objects::isNull);
            List<EmpInfoDO> empInfoList = selectImportEmpByIdCardList(companyId, idCardList, tokenUser);
            Map<String, String> idCardMap = new HashMap<>(256);
            Map<String, EmpInfoDO> idCardMap1 = new HashMap<>(256);
            if (!CollectionUtils.isEmpty(empInfoList)) {
                idCardMap = empInfoList.stream()
                        .collect(Collectors.toMap(EmpInfoDO::getIdCard, EmpInfoDO::getId));
                idCardMap1 = empInfoList.stream()
                        .collect(Collectors.toMap(EmpInfoDO::getIdCard, p -> p));
            }
            for (EmpInfoImportDTO empInfoImportDTO : importSucList) {
                if (!StringUtils.isEmpty(empInfoImportDTO.getIdCard())) {
                    String empId = idCardMap.get(empInfoImportDTO.getIdCard());
                    if (!StringUtils.isEmpty(empId)) {
                        empInfoImportDTO.setEmpId(empId);
                        empInfoImportDTO.setStatus(idCardMap1.get(empInfoImportDTO.getIdCard()).getStatus());
                        empInfoImportDTO.setFormalType(idCardMap1.get(empInfoImportDTO.getIdCard()).getFormalType());
                    }
                }
            }
        }
        // 返回的信息
        empImportExcelVO.setImportAllList(new ArrayList<>());
        empImportExcelVO.setImportSucList(importSucList);
        empImportExcelVO.setImportFailList(importFailList);
        // 有失败的直接导出文件
        if (!CollectionUtils.isEmpty(importFailList)) {
            String filenames = exportFailData(importFailList, isAdd, tokenUser);
            empImportExcelVO.setExcelFilePath(filenames);
            Set<String> header = importFailList.get(0).getAllMap().keySet();
            empImportExcelVO.setFailHeaders(new ArrayList<>(header));
        }

        try {
            for (EmpInfoDO empInfoDO : empInfoAddList) {
                OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
                operationEmpRecordAddDTO.setEmpId(empInfoDO.getId());
                operationEmpRecordAddDTO.setEmpStatus(3);
                operationEmpRecordAddDTO.setQueryType(2);
                operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                operationEmpRecordAddDTO.setUserId(empInfoDO.getUserId());
                operationEmpRecordAddDTO.setSourceType(1);
                operationEmpRecordAddDTO.setSourceTypeInfo("PC入职");
                operationEmpRecordAddDTO.setCompanyId(empInfoDO.getCompanyId());
                operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.saveExcelDataList");
                operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
            }
        } catch (Exception e) {
            log.error("员工记录异常");
        }
        return empImportExcelVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public EmpImportExcelVO asyncSaveExcelDataList(List<EmpInfoImportDTO> list, boolean isAdd, String companyId,
                                                   TokenUser tokenUser) {
        long l1 = System.currentTimeMillis();

        //  2.校验导入信息
        EmpImportExcelVO empImportExcelVO = checkImportData(list, companyId, isAdd, tokenUser);
        long l2 = System.currentTimeMillis();
        log.info("校验{}条信息，耗时{}ms", list.size(), (l2 - l1));

        List<EmpInfoImportDTO> failList = empImportExcelVO.getImportFailList();
        if (!CollectionUtils.isEmpty(failList)) {
            // 错误数据导出
            String failData = exportFailData(empImportExcelVO.getImportFailList(), isAdd, tokenUser);
            empImportExcelVO.setExcelFilePath(failData);
            // 写入表头
            Set<String> header = list.get(0).getAllMap().keySet();
            empImportExcelVO.setFailHeaders(new ArrayList<>(header));

        }
        //  5.return
        return empImportExcelVO;
    }

    @Override
    public EmpImportExcelVO asyncSaveExcelDataListBySite(List<EmpInfoImportDTO> list, boolean isAdd, TokenUser tokenUser) {
        EmpImportExcelVO empImportExcelVO = new EmpImportExcelVO();
        empImportExcelVO.setImportSucList(new ArrayList<>());
        empImportExcelVO.setImportFailList(new ArrayList<>());
        empImportExcelVO.setEmpInfoAddList(new ArrayList<>());
        empImportExcelVO.setEmpInfoUpdateList(new ArrayList<>());
        Map<String, List<EmpInfoImportDTO>> companyIdListMap = list.parallelStream()
                .collect(Collectors.groupingBy(EmpInfoImportDTO::getCompanyId));
        for (String companyId : companyIdListMap.keySet()) {
            List<EmpInfoImportDTO> empInfoImportDTOList = companyIdListMap.get(companyId);
            if (StringUtils.isBlank(companyId)) {
                empImportExcelVO.getImportFailList().addAll(empInfoImportDTOList);
                continue;
            }
            //  2.校验导入信息 过滤非本用工单位员工
            EmpImportExcelVO companyImportExcel = checkImportData(empInfoImportDTOList, companyId, isAdd, tokenUser);
            empImportExcelVO.getImportSucList().addAll(companyImportExcel.getImportSucList());
            empImportExcelVO.getImportFailList().addAll(companyImportExcel.getImportFailList());
            empImportExcelVO.getEmpInfoAddList().addAll(companyImportExcel.getEmpInfoAddList());
            empImportExcelVO.getEmpInfoUpdateList().addAll(companyImportExcel.getEmpInfoUpdateList());
        }
        List<EmpInfoImportDTO> failList = empImportExcelVO.getImportFailList();
        if (!CollectionUtils.isEmpty(failList)) {
            // 错误数据导出
            String failData = exportFailData(empImportExcelVO.getImportFailList(), isAdd, tokenUser);
            empImportExcelVO.setExcelFilePath(failData);
            // 写入表头
            Set<String> header = list.get(0).getAllMap().keySet();
            empImportExcelVO.setFailHeaders(new ArrayList<>(header));

        }
        return empImportExcelVO;
    }

    /**
     * 校验花名册导入数据
     *
     * @param list      导入数据
     * @param companyId 用工单位id
     * @param isAdd     是否新增 true：新增 false：修改
     * @param tokenUser 当前用户
     * @return EmpImportExcelVO
     */
    private EmpImportExcelVO checkImportData(List<EmpInfoImportDTO> list, String companyId, boolean isAdd, TokenUser tokenUser) {
        // 地区
        List<AreaReduceVO> areaList = adminProviderService.listAllArea();

        //  站点下所有在职员工
        List<EmpReduceInfoVO> empReduceList = empInfoDAO.listOnJobEmpReduceBySite(tokenUser.getSiteId());
        // map<手机号,此手机号对应的员工>
        Map<String, List<EmpReduceInfoVO>> empPhoneMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empReduceList)) {
            if (isAdd) {
                empPhoneMap = empReduceList.parallelStream().collect(
                        Collectors.groupingBy(EmpReduceInfoVO::getPhone));
            } else {
                empPhoneMap = empReduceList.parallelStream()
                        .filter(s -> EmpInfoStatus.HAS_ENTRY.getValue().equals(s.getStatus())
                                || WAIT_QUIT.getValue().equals(s.getStatus()))
                        .collect(Collectors.groupingBy(EmpReduceInfoVO::getPhone));
            }
        }
        // map<身份证号,此身份证号对应的员工>
        Map<String, List<EmpReduceInfoVO>> empIdCardMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(empReduceList)) {
            if (isAdd) {
                empIdCardMap = empReduceList.parallelStream()
                        .filter(s -> StrKit.isNotEmpty(s.getIdCard())).collect(
                                Collectors.groupingBy(EmpReduceInfoVO::getIdCard));
            } else {
                empIdCardMap = empReduceList.parallelStream()
                        .filter(s -> StrKit.isNotEmpty(s.getIdCard())
                                && (EmpInfoStatus.HAS_ENTRY.getValue().equals(s.getStatus())
                                || WAIT_QUIT.getValue().equals(s.getStatus()))).collect(
                                Collectors.groupingBy(EmpReduceInfoVO::getIdCard));
            }

        }
        // excel中重复手机号
        Map<String, List<EmpInfoImportDTO>> phoneImportMap = list.parallelStream()
                .filter(empInfo -> StringUtils.isNotEmpty(empInfo.getPhone()))
                .collect(Collectors.groupingBy(EmpInfoImportDTO::getPhone));

        // excel中重复身份证号
        Map<String, List<EmpInfoImportDTO>> icCardImportMap = list.parallelStream()
                .filter(empInfo -> StringUtils.isNotEmpty(empInfo.getIdCard()))
                .collect(Collectors.groupingBy(EmpInfoImportDTO::getIdCard));

        // 处理导入数据
        log.info("花名册导入数据,循环处理导入数据开始,时间戳:{}", System.currentTimeMillis());
        List<String> channelNameList = list.stream()
                .map(EmpInfoImportDTO::getChannelName).distinct().collect(Collectors.toList());
        channelNameList.removeIf(Objects::isNull);
        List<ChannelDO> channelList = channelService.selectByNameList(channelNameList, tokenUser.getSiteId());
        Map<String, ChannelDO> channelMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(channelList)) {
            channelMap = channelList.stream().collect(Collectors.toMap(ChannelDO::getName, v -> v));
        }
        List<String> importPhoneList = list.stream()
                .map(EmpInfoImportDTO::getPhone).distinct().collect(Collectors.toList());
        importPhoneList.removeIf(Objects::isNull);
        List<CheckInPeopleDO> checkInPeopleList = checkInPeopleService.selectByPhoneList(importPhoneList, tokenUser.getSiteId());
        Map<String, CheckInPeopleDO> checkInPeopleMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(checkInPeopleList)) {
            checkInPeopleMap = checkInPeopleList.stream().collect(Collectors.toMap(CheckInPeopleDO::getPhone, v -> v));
        }

        // 手机号分组
        Map<String, List<EmpInfoDO>> resignByPhoneMap = new HashMap<>();
        if (isAdd) {
            // 手机号是离职员工的
            List<String> resignPhoneList = list.parallelStream().map(EmpInfoImportDTO::getPhone)
                    .filter(StrKit::isNotEmpty).distinct().collect(Collectors.toList());
            List<EmpInfoDO> resignByPhoneList = listEmpResignByPhone(companyId, resignPhoneList, tokenUser);
            resignByPhoneMap = resignByPhoneList.parallelStream()
                    .collect(Collectors.groupingBy(EmpInfoDO::getPhone));
        }

        // 身份证号是离职员工的
        List<String> resignIdCardList = list.parallelStream().map(EmpInfoImportDTO::getIdCard)
                .filter(StrKit::isNotEmpty).distinct().collect(Collectors.toList());
        List<EmpInfoDO> resignByIdCardList = listEmpResignByIdCard(companyId, resignIdCardList, tokenUser);
        // 身份证分组
        Map<String, List<EmpInfoDO>> resignByIdCardMap = resignByIdCardList.parallelStream()
                .collect(Collectors.groupingBy(EmpInfoDO::getIdCard));

        //成功导入列表
        List<EmpInfoImportDTO> importSucList = new ArrayList<>();
        //失败导入列表
        List<EmpInfoImportDTO> importFailList = new ArrayList<>();

        // 新增的员工
        List<EmpInfoDO> empInfoAddList = new ArrayList<>();
        // 修改的员工
        List<EmpInfoDO> empInfoUpdateList = new ArrayList<>();

        for (EmpInfoImportDTO empInfoImportDTO : list) {
            empInfoImportDTO.setJoinDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setJoinWorkDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setTurnStraightDateStr(DateKit8.format2Date(empInfoImportDTO.getJoinDate()));
            empInfoImportDTO.setContractStartDateStr(DateKit8.format2Date(empInfoImportDTO.getContractEndDate()));
            empInfoImportDTO.setContractEndDateStr(DateKit8.format2Date(empInfoImportDTO.getContractStartDate()));

            if (empInfoImportDTO.getReason() != null) {
                importFailList.add(empInfoImportDTO);
                continue;
            }
            //  姓名不能为空
            if (StrKit.isEmpty(empInfoImportDTO.getName()) && isAdd) {
                empInfoImportDTO.setReason("员工姓名：为空");
                empInfoImportDTO.setField("name");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 身份证不能为空
            String idCard = empInfoImportDTO.getIdCard();
            if (StrKit.isEmpty(idCard)) {
                empInfoImportDTO.setReason("身份证号：为空");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 手机号不能为空
            if (StrKit.isEmpty(empInfoImportDTO.getPhone()) && isAdd) {
                empInfoImportDTO.setReason("手机号：为空");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 邮箱格式校验
            if (StrKit.isNotEmpty(empInfoImportDTO.getEmail()) && !RegUtils.isEmail(empInfoImportDTO.getEmail())) {
                empInfoImportDTO.setReason("个人邮箱：格式有误，请参考模板");
                empInfoImportDTO.setField("email");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 工作性质不能为空
            if (Objects.isNull(empInfoImportDTO.getPostType()) && isAdd) {
                empInfoImportDTO.setReason("工作性质：为空");
                empInfoImportDTO.setField("postType");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 入职时间不能为空
            if (Objects.isNull(empInfoImportDTO.getJoinDate()) && isAdd) {
                empInfoImportDTO.setReason("入职时间：为空");
                empInfoImportDTO.setField("joinDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 退休年龄格式
            if (!Objects.isNull(empInfoImportDTO.getRetirementAge())) {
                if (empInfoImportDTO.getRetirementAge() <= 0) {
                    empInfoImportDTO.setReason("退休年龄：非正整数");
                    empInfoImportDTO.setField("retirementAge");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            if (!Objects.isNull(empInfoImportDTO.getAllMap())) {
                Map<String, String> allMap = empInfoImportDTO.getAllMap();
                // 养老保险格式
                String pf1 = allMap.get("养老保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("养老保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 失业保险格式
                pf1 = allMap.get("失业保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("失业保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 工伤保险格式
                pf1 = allMap.get("工伤保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("工伤保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 医疗保险格式
                pf1 = allMap.get("医疗保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("医疗保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 生育保险格式
                pf1 = allMap.get("生育保险");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("生育保险基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 公积金格式
                pf1 = allMap.get("公积金");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1)) {
                        if (Double.parseDouble(pf1) > 0) {
                            String[] split = pf1.split("\\.");
                            if (split.length == 2 && split[1].length() > 2) {
                                empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        } else {
                            empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("公积金基数：格式有误，请输入正数且最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 公积金比例格式
                pf1 = allMap.get("公积金比例");
                if (!StringUtils.isEmpty(pf1)) {
                    if (Validator.isNumber(pf1) && Double.parseDouble(pf1) >= 5 && Double.parseDouble(pf1) <= 12) {
                        String[] split = pf1.split("\\.");
                        if (split.length == 2 && split[1].length() > 2) {
                            empInfoImportDTO.setReason("公积金比例：格式有误；输入范围5-12，最多保留两位小数");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    } else {
                        empInfoImportDTO.setReason("公积金比例：格式有误；输入范围5-12，最多保留两位小数");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                }
                // 起缴时间格式
                pf1 = allMap.get("起缴时间");
                if (!StringUtils.isEmpty(pf1)) {
                    String[] split1 = pf1.split("-");
                    if (split1.length != 2) {
                        String[] split2 = pf1.split("/");
                        if (split2.length != 2) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        } else {
                            if (!Validator.isNumber(split2[1]) || Integer.parseInt(split2[1]) > 12) {
                                empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                                empInfoImportDTO.setField("");
                                importFailList.add(empInfoImportDTO);
                                continue;
                            }
                        }
                    } else {
                        if (!Validator.isNumber(split1[1]) || Integer.parseInt(split1[1]) > 12) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    }
                    try {
                        DateUtil.parse(pf1, "yyyy-MM");
                    } catch (Exception e) {
                        try {
                            DateUtil.parse(pf1, "yyyy/MM");
                        } catch (Exception exception) {
                            empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                            empInfoImportDTO.setField("");
                            importFailList.add(empInfoImportDTO);
                            continue;
                        }
                    }
                    String[] split = null;
                    if (pf1.contains("/")) {
                        split = pf1.split("/");
                    } else if (pf1.contains("-")) {
                        split = pf1.split("-");
                    }
                    if (split.length != 2) {
                        empInfoImportDTO.setReason("起缴时间：格式有误，正确格式为2021-05");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }

                }
                //参保城市格式
                pf1 = allMap.get("参保城市");
                if (!StringUtils.isEmpty(pf1)) {
                    String reback = FormatUtils.checkCity(pf1, areaList);
                    if (StringUtils.isEmpty(reback)) {
                        empInfoImportDTO.setReason("缴纳地址：格式有误，请参考模板");
                        empInfoImportDTO.setField("");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    } else {
                        allMap.put("参保城市", pf1);
                    }
                }
            }
            // 身份证号格式
            if (!RegUtils.isIdCardAllType(idCard.toUpperCase())) {
                empInfoImportDTO.setReason("身份证号：格式有误");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验手机号是否在本公司的离职列表
            if (StrKit.isNotEmpty(empInfoImportDTO.getPhone())
                    && resignByPhoneMap.containsKey(empInfoImportDTO.getPhone())) {
                empInfoImportDTO.setReason("手机号：员工已存在于该用工单位的已离职列表，请直接为其更换用工单位");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验身份证是否在本公司的离职列表
            if (StrKit.isNotEmpty(empInfoImportDTO.getIdCard())
                    && resignByIdCardMap.containsKey(idCard)) {
                empInfoImportDTO.setReason("身份证号：员工已存在于该用工单位的已离职列表，请直接为其更换用工单位");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 校验证件类型
            Integer cardType = RegUtils.cardType(idCard);
            empInfoImportDTO.setCertificateType(cardType);
            // 校验员工合同期限
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() == null) {
                if (empInfoImportDTO.getProbationDays() != null) {
                    // 试用期不为空 转正日期 = 入职日期 + 试用期
                    empInfoImportDTO.setTurnStraightDate(DateKit8.addDays(empInfoImportDTO.getJoinDate()
                            , empInfoImportDTO.getProbationDays()));
                } else {
                    // 试用期为空 转正日期 = 入职日期
                    empInfoImportDTO.setTurnStraightDate(empInfoImportDTO.getJoinDate());
                }
            }

            // 转正日期不能早于入职日期
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() != null
                    && empInfoImportDTO.getJoinDate().getTime() > empInfoImportDTO.getTurnStraightDate().getTime()) {
                // 已入职其他公司
                empInfoImportDTO.setReason("转正日期：转正日期需大于等于入职日期");
                empInfoImportDTO.setField("turnStraightDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }

            if (!org.springframework.util.StringUtils.isEmpty(empInfoImportDTO.getBirthday())) {
                String stringBuilder = empInfoImportDTO.getBirthday() + " " +
                        "00:00:00";
                empInfoImportDTO.setBirthday(stringBuilder);
            }
            // 转正日期大于现在是试用期
            if (Objects.isNull(empInfoImportDTO.getFormalType()) && Objects.nonNull(empInfoImportDTO.getTurnStraightDate())) {
                empInfoImportDTO.setFormalType(empInfoImportDTO.getTurnStraightDate().getTime()
                        > System.currentTimeMillis() ? 1 : 2);
            }

            // 手机号格式
            if (!RegUtils.isMobile(empInfoImportDTO.getPhone()) && isAdd) {
                // 手机号格式
                empInfoImportDTO.setReason("手机号：格式有误");
                empInfoImportDTO.setField("phone");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 重复手机号
            if (phoneImportMap.containsKey(empInfoImportDTO.getPhone())) {
                List<EmpInfoImportDTO> phoneList = phoneImportMap.get(empInfoImportDTO.getPhone());
                if (!CollectionUtils.isEmpty(phoneList) && phoneList.size() > 1) {
                    empInfoImportDTO.setReason("手机号：已存在");
                    empInfoImportDTO.setField("phone");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            // 重复身份证号
            if (icCardImportMap.containsKey(idCard)) {
                List<EmpInfoImportDTO> idCardList = icCardImportMap.get(idCard);
                if (!CollectionUtils.isEmpty(idCardList) && idCardList.size() > 1) {
                    empInfoImportDTO.setReason("身份证号：已存在");
                    empInfoImportDTO.setField("idCard");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }
            // 员工转正时间不能早于入职时间
            if (empInfoImportDTO.getJoinDate() != null && empInfoImportDTO.getTurnStraightDate() != null
                    && empInfoImportDTO.getTurnStraightDate().before(empInfoImportDTO.getJoinDate())) {
                empInfoImportDTO.setReason("员工转正时间不能早于入职时间");
                empInfoImportDTO.setField("turnStraightDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 学历校验
            if (StrKit.isNotEmpty(empInfoImportDTO.getEducation())) {
                EducationLevelEnum byDesc = EducationLevelEnum.findByDesc(empInfoImportDTO.getEducation());
                if (Objects.isNull(byDesc)) {
                    empInfoImportDTO.setReason("学历：请填写系统数据");
                    empInfoImportDTO.setField("education");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }

            // 渠道
            if (StringUtils.isNotBlank(empInfoImportDTO.getChannelName())) {
                ChannelDO channelDO = channelMap.get(empInfoImportDTO.getChannelName());
                if (Objects.isNull(channelDO)) {
                    empInfoImportDTO.setReason("渠道来源：系统中无此渠道来源");
                    empInfoImportDTO.setField("channelName");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }


                // 保存渠道信息
                empInfoImportDTO.setChannelId(channelDO.getId());
                CheckInPeopleDO checkInPeopleDO = checkInPeopleMap.get(empInfoImportDTO.getPhone());
                if (Objects.nonNull(checkInPeopleDO)) {
                    CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                    checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                    checkInPeopleUpdateDTO.setChannelId(channelDO.getId());
                    checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
                } else {
                    // 新建预登记人员（来源为花名册）
                    CheckInPeopleAddDTO checkInPeopleAddDTO = new CheckInPeopleAddDTO();
                    checkInPeopleAddDTO.setName(empInfoImportDTO.getName());
                    checkInPeopleAddDTO.setPhone(empInfoImportDTO.getPhone());
                    checkInPeopleAddDTO.setIdcard(idCard);
                    checkInPeopleAddDTO.setChannelId(channelDO.getId());
                    checkInPeopleAddDTO.setSource(HrConstants.HUW);
                    checkInPeopleAddDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
                    checkInPeopleAddDTO.setWorkStatus(CheckInPeopleConstant.WORK_STATUS_RNTRY);
                    checkInPeopleService.save(checkInPeopleAddDTO, tokenUser);
                }
            }
            if (StrKit.isNotEmpty(empInfoImportDTO.getTag())) {
                String tag = empInfoImportDTO.getTag();
                // 将中文逗号替换为英文逗号
                tag = tag.replaceAll("，", ",");
                // 只有逗号不作为标签写入
                if (!",".equals(tag)) {
                    String[] array = tag.split(",");
                    List<String> tagList = Arrays.asList(array);
                    if (tagList.size() > MAX_TAG_COUNT) {
                        empInfoImportDTO.setReason("员工最多添加" + MAX_TAG_COUNT + "个标签");
                        empInfoImportDTO.setField("tag");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                    for (String tagItem : tagList) {
                        // 更新标签库
                        empTagService.saveTagByCompanyId(companyId, tagItem, tokenUser);
                    }
                    empInfoImportDTO.setTag(tag);
                }
            }

            // 校验员工合同期限
            if (StringUtils.isNotBlank(empInfoImportDTO.getContractExpireStr())) {
                try {
                    int parseInt;
                    if (empInfoImportDTO.getContractExpireStr().contains("年")) {
                        parseInt = Integer.parseInt(empInfoImportDTO.getContractExpireStr().replace("年", ""));
                        // 结束日期计算补全
                        if (empInfoImportDTO.getContractEndDate() == null && empInfoImportDTO.getContractStartDate() != null) {
                            Date date = DateKit8.addMonths(empInfoImportDTO.getContractStartDate(), parseInt * 12L);
                            empInfoImportDTO.setContractEndDate(DateKit8.addDays(date, -1));
                        }
                    } else if (empInfoImportDTO.getContractExpireStr().contains("月")) {
                        parseInt = Integer.parseInt(empInfoImportDTO.getContractExpireStr().replace("月", ""));
                        // 结束日期计算补全
                        if (empInfoImportDTO.getContractEndDate() == null && empInfoImportDTO.getContractStartDate() != null) {
                            Date date = DateKit8.addMonths(empInfoImportDTO.getContractStartDate(), parseInt);
                            empInfoImportDTO.setContractEndDate(DateKit8.addDays(date, -1));
                        }
                    } else {
                        // 合同期限：格式有误
                        empInfoImportDTO.setReason("合同期限：格式有误");
                        empInfoImportDTO.setField("timeLimit");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                    if (parseInt < 0 || parseInt > 10) {
                        // 合同期限：格式有误
                        empInfoImportDTO.setReason("合同期限：格式有误");
                        empInfoImportDTO.setField("timeLimit");
                        importFailList.add(empInfoImportDTO);
                        continue;
                    }
                } catch (NumberFormatException e) {
                    // 合同期限：格式有误
                    empInfoImportDTO.setReason("合同期限：格式有误");
                    empInfoImportDTO.setField("timeLimit");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
            }

            // 合同结束日期不能早于开始日期
            if (empInfoImportDTO.getContractStartDate() != null && empInfoImportDTO.getContractEndDate() != null
                    && empInfoImportDTO.getContractStartDate().getTime() > empInfoImportDTO.getContractEndDate().getTime()) {
                // 已入职其他公司
                empInfoImportDTO.setReason("合同结束时间：合同结束时间需大于等于合同开始时间");
                empInfoImportDTO.setField("contractEndDate");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            // 合同类型校验
            if (StringUtils.isNotBlank(empInfoImportDTO.getContractType())) {
                //合同类型
                FileType fileType = FileType.findByDesc(empInfoImportDTO.getContractType());
                if (fileType == null) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("合同类型：格式有误");
                    empInfoImportDTO.setField("contractType");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                empInfoImportDTO.setFileTypeValue(fileType.getValue());
            }
            // 身份证号在租户的员工
            List<EmpReduceInfoVO> empReduceInfoVOList = empIdCardMap.get(idCard);
            // 身份证号在用工单位的员工
            if (!CollectionUtils.isEmpty(empReduceInfoVOList)) {
                empReduceInfoVOList = empReduceInfoVOList.parallelStream().filter(empReduceInfoVO
                        -> companyId.equals(empReduceInfoVO.getCompanyId())).collect(Collectors.toList());
            }
            ///////////////////////////////// 新增操作 /////////////////////////////////
            if (isAdd) {
                // 新增时需要满足：
                // 1、手机号不能在租户存在
                if (empPhoneMap.containsKey(empInfoImportDTO.getPhone())) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("手机号：手机号已有员工信息");
                    empInfoImportDTO.setField("phone");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                // 2、用工单位下不能有同身份证的
                if (!CollectionUtils.isEmpty(empReduceInfoVOList)) {
                    // 已入职其他公司
                    empInfoImportDTO.setReason("身份证号：身份证号已存在");
                    empInfoImportDTO.setField("idCard");
                    importFailList.add(empInfoImportDTO);
                    continue;
                }
                // 尚未入职,新增
                EmpInfoDO empInfoAdd = empInfoImportDTO.to(EmpInfoDO.class);
                empInfoAdd.setSalaryType(SalaryFileTypeEnum.NO_SALARY.getValue());
                empInfoAddList.add(empInfoAdd);
                importSucList.add(empInfoImportDTO);
                continue;
            }
            ///////////////////////////////// 更新操作 /////////////////////////////////
            // 修改时需要满足：身份证需要在用工单位存在
            if (CollectionUtils.isEmpty(empReduceInfoVOList)) {
                // 身份证不在用工单位存在
                empInfoImportDTO.setReason("身份证号：此员工不是该用工单位的在职员工，请验证后重新导入");
                empInfoImportDTO.setField("idCard");
                importFailList.add(empInfoImportDTO);
                continue;
            }
            EmpReduceInfoVO empReduceInfoVO = empReduceInfoVOList.get(0);
            // 更新
            EmpInfoDO empInfoUp = empInfoImportDTO.to(EmpInfoDO.class);
            empInfoUp.setId(empReduceInfoVO.getId());
            //放入手机号后面同步预登记数据用
            empInfoUp.setPhone(empReduceInfoVO.getPhone());
            // 写入userId，后面发通知要用
            empInfoUp.setUserId(empReduceInfoVO.getUserId());
            empInfoUpdateList.add(empInfoUp);
            importSucList.add(empInfoImportDTO);
        }
        log.info("花名册导入数据,循环处理导入数据结束,时间戳:{}", System.currentTimeMillis());
        EmpImportExcelVO empImportExcelVO = new EmpImportExcelVO();
        empImportExcelVO.setImportSucList(importSucList);
        empImportExcelVO.setImportFailList(importFailList);
        empImportExcelVO.setEmpInfoAddList(empInfoAddList);
        empImportExcelVO.setEmpInfoUpdateList(empInfoUpdateList);
        return empImportExcelVO;

    }

    /**
     * 导出错误数据
     */
    private String exportFailData(List<EmpInfoImportDTO> exportFailList, Boolean isAdd, TokenUser tokenUser) {
        // 表头容器定义
        List<List<String>> headList = new ArrayList<>();
        // 所有的数据容器定义
        List<List<String>> dataList = new ArrayList<>();
        List<String> wrongsCause = new ArrayList<>();
        wrongsCause.add("错误原因");
        headList.add(wrongsCause);
        Map<String, String> allMap = exportFailList.get(0).getAllMap();
        for (String head : allMap.keySet()) {
            List<String> oneHead = new ArrayList<>();
            oneHead.add(head);
            headList.add(oneHead);
        }
        for (EmpInfoImportDTO empInfoImportDTO : exportFailList) {
            List<String> oneDate = new ArrayList<>();
            Map<String, String> empAllMap = empInfoImportDTO.getAllMap();
            oneDate.add(empInfoImportDTO.getReason());
            for (String headMsg : allMap.keySet()) {
                oneDate.add(empAllMap.get(headMsg));
            }
            dataList.add(oneDate);
        }
        // 导出excel
        String excelFilePath = ExcelKit.exportExcelDynamic("employeeRosterTemplateZhiXinRen", "员工数据",
                dataList, headList);
        String cleanPath = org.springframework.util.StringUtils.cleanPath(excelFilePath);
        File file = new File(excelFilePath);
        log.info("本地路径：" + file.getPath());

        FileItem fileItem = createFileItem(file);
        CommonsMultipartFile[] commonsMultipartFiles = new CommonsMultipartFile[1];
        commonsMultipartFiles[0] = new CommonsMultipartFile(fileItem);
        String fileName = "";
        String format = DateUtil.format(new Date(), "yyyy.MM.dd");
        if (isAdd) {
            fileName = "花名册导入错误数据-" + format;
        } else {
            fileName = "花名册修改错误数据-" + format;
        }
        List<String> list =
                fileProviderService.uploadAndSetName(commonsMultipartFiles, "inline", fileName, tokenUser);
        if (!CollectionUtils.isEmpty(list)) {
            return list.get(0);
        }
        return null;
    }

    /**
     * File 转 FileItem
     */
    private FileItem createFileItem(File file) {
        FileItemFactory factory = new DiskFileItemFactory(16, null);
        FileItem item = factory.createItem("textField", "text/plain", true, file.getName());
        int bytesRead;
        byte[] buffer = new byte[8192];
        try {
            FileInputStream fis = new FileInputStream(file);
            OutputStream os = item.getOutputStream();
            while ((bytesRead = fis.read(buffer, 0, 8192)) != -1) {
                os.write(buffer, 0, bytesRead);
            }
            os.close();
            fis.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return item;
    }

    /**
     * 员工信息补全,补充员工的一些,共用信息处理,处理完成后进行保存
     *
     * @param empInfoList 员工列表
     * @param isAdd       是否是新增,true:新增;false:修改
     * @param companyId   公司id
     * @param tokenUser   当前用户
     */
    private void empInfoComplementAndSave(List<EmpInfoDO> empInfoList, Boolean isAdd, String companyId, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(empInfoList)) {
            return;
        }
        // 所有地区
        List<AreaReduceVO> areaList = adminProviderService.listAllArea();
        // 员工信息补全
        log.info("花名册导入数据,员工信息补全开始,时间戳:{}", System.currentTimeMillis());
        empInfoList.parallelStream().forEach(
                empInfo -> {
                    // 新增
                    if (isAdd) {
                        // 证件类型(默认居民身份证)
                        if (empInfo.getCertificateType() == null) {
                            empInfo.setCertificateType(CertificateTypeEnum.ID_CARD.getValue());
                        }
                        // 国籍 默认中国
                        if (empInfo.getNationality() == null) {
                            empInfo.setNationality(NATIONALITY);
                        }
                        // 任职受雇从业类型(默认雇员)
                        if (empInfo.getEmploymentType() == null) {
                            empInfo.setEmploymentType(EMPLOYMENT_TYPE);
                        }
                        // 薪资档案类型；0：未定薪 1：固定薪资档案 2：工价薪资档案
                        if (empInfo.getSalaryType() == null) {
                            empInfo.setSalaryType(SalaryFileTypeEnum.NO_SALARY.getValue());
                        }
                        if (empInfo.getEmployType() == null) {
                            // 聘用形式（0：非正式，1：正式）
                            empInfo.setEmployType(true);
                        }
                        if (empInfo.getFormalType() == null) {
                            // 正式类型（0：无状态，1：试用期，2：已转正）
                            empInfo.setFormalType(2);
                        }
                        if (empInfo.getJoinFormStatus() == null) {
                            // 入职登记表状态（0：未提交，1：已提交）
                            empInfo.setJoinFormStatus(false);
                        }
                        if (empInfo.getEmpSocStatus() == null) {
                            // 未参保
                            empInfo.setEmpSocStatus(NOT_SOC.getValue());
                        }
                        if (empInfo.getPostType() == null) {
                            // 岗位类型
                            empInfo.setPostType(PostType.LABOUR.getValue());
                        }
                        if (empInfo.getContractsStatus() == null) {
                            // 合同状态（0:合同未发起;1:待员工签署;2:带公司签署;3:签署完成）
                            empInfo.setContractsStatus(0);
                        }
                        //实名认证
                        empInfo.setVerified(false);
                        // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
                        empInfo.setChangeStatus(0);
                        // 员工状态
                        empInfo.setStatus(HAS_ENTRY.getValue());
                        // 审批状态
                        empInfo.setApprovalStatus(ApprovalStatusEnum.APPRO_DISABLE.getValue());
                        //添加信息完善默认值默认值
                        empInfo.setIsImprove(false);
                        //给名字添加拼音
                        empInfo.setNamePinyin(PinyinKit.nameToPinyin(empInfo.getName()));
                        // 通用字段
                        empInfo.setCompanyId(companyId);
                        empInfo.preInsert(tokenUser.getUserId());
                        empInfo.setSiteId(tokenUser.getSiteId());
                        if (empInfo.getIdCard() != null) {
                            String idCard = empInfo.getIdCard();
                            if (RegUtils.isIdCard(idCard)) {
                                // 拿身份证号辨别性别,年龄,身份证号
                                if (empInfo.getIdCard().length() == 18) {
                                    empInfo.setGender(Integer.parseInt(idCard.substring(16, 17)) % 2 == 0 ? 2 : 1);
                                    empInfo.setEmpAge(Integer.parseInt(DateUtils.getYearAndMonth(new Date())[0]) - Integer.parseInt(idCard.substring(6, 10)));
                                    empInfo.setBirthday(idCard.substring(6, 10) + "-" + idCard.substring(10, 12) + "-" + idCard.substring(12, 14) + " 00:00:00");
                                } else if (empInfo.getIdCard().length() == 15) {
                                    empInfo.setGender(Integer.parseInt(idCard.substring(13, 14)) % 2 == 0 ? 2 : 1);
                                    empInfo.setEmpAge(Integer.parseInt(DateUtils.getYearAndMonth(new Date())[0]) - Integer.parseInt(idCard.substring(6, 8)) - 1901);
                                    empInfo.setBirthday("19" + idCard.substring(6, 8) + "-" + idCard.substring(8, 10) + "-" + idCard.substring(10, 12) + " 00:00:00");
                                }
                            }
                        }

                    }
                    //入职城市
                    if (StringUtils.isNotBlank(empInfo.getJoinCityName())) {
                        empInfo.setJoinCityCode(getAreaInfoByName(areaList, empInfo.getJoinCityName()));
                    }

                    //工资卡开户城市
                    if (StringUtils.isNotBlank(empInfo.getBankPlace())) {
                        empInfo.setBankPlace(getAreaInfoByName(areaList, empInfo.getBankPlace()));
                    }
                    // 渠道
                    if (StringUtils.isNotBlank(empInfo.getRecruitChannels())) {
                        ChannelVO channelVO = channelService
                                .selectByName(empInfo.getRecruitChannels(), tokenUser.getSiteId());
                        if (channelVO != null) {
                            empInfo.setChannelId(channelVO.getId());
                        }
                    }
                    // 根据入职时间和转正时间获取员工状态
                    checkEmpProbationAndFormalBatch(empInfo);
                }
        );
        log.info("花名册导入数据,员工信息补全结束,时间戳:{}", System.currentTimeMillis());
        // 员工信息更新或保存
        if (isAdd) {
            // 新增先批量保存一下,生成主键id,便于后续使用
            empInfoDAO.insertListAndSetId(empInfoList);
        } else {
            //修改退休信息发送退休通知
            sendRetirement(empInfoList);
            empInfoList.forEach(empInfoDO -> {
                EmpInfoDO empInfoDO1 = selectById(empInfoDO.getId());
                if (!StringUtils.isEmpty(empInfoDO.getBankCard()) && !StringUtils.isEmpty(empInfoDO1.getBankCard()) && !empInfoDO.getBankCard().equals(empInfoDO1.getBankCard())) {
                    //工资条更改变动通知
                    try {
                        empInfoDO.setUserId(empInfoDO1.getUserId());
                        empInfoDO.setCompanyId(companyId);
                        sendNoticeService.salaryChangeSendNotice(empInfoDO, companyId, tokenUser);
                    } catch (Exception e) {
                        log.error("员工工资卡变更发送消息失败,{}", e.getMessage());
                    }
                }
                updateByIdSelective(empInfoDO, empInfoDO.getSiteId(), tokenUser.getUserId());
                //修改预登记渠道
                updateCheckInChannel(empInfoDO, tokenUser);
            });
        }
//        //发送人员变动消息通知
//        empInfoList.forEach(empInfoDO -> sendNotice(empInfoDO, tokenUser));

//        // 所有部门
//        List<DepInfoDO> depInfoList = depInfoService.listByCompanyId(companyId, tokenUser.getSiteId());
//        // 所有部门
//        List<PositionInfoDO> positionInfoList = positionInfoService.listByCompanyId(companyId, tokenUser.getSiteId());
        String desc = PersonalEventExample.INSERT_INTO_ADMIN + tokenUser.getUserName() + PersonalEventExample.INSERT_INTO_SYS;
        // 其他操作,部门,岗位,合同,开通用户
        log.info("花名册导入数据,其他操作开始,时间戳:{}", System.currentTimeMillis());
        // 部门 第一层是租户层 第二层是用工单位层 根据用工单位Id查询 name不传 结果唯一
        DepInfoDO companyDepInfoDO = depInfoService.selectByNameAndLevel(null, 2, null, companyId, tokenUser);
        //岗位
        PositionInfoDO positionInfoDO = positionInfoService
                .selectByNameAndLevel(null, 1, null, companyId, tokenUser);
        // 部门名称(全路径)-部门Id
        Map<String, String> depNameIdMap = new HashMap<>();
        for (EmpInfoDO empInfo : empInfoList) {
            if (isAdd) {
                // 新员工,开通用户
                userProviderService.registerAccount(empInfo.getName(), empInfo.getPhone(), tokenUser, companyId);
                personalEventService.autoSave(empInfo.to(EmpInfoVO.class), tokenUser, desc, PersonalEventEnum.ADD.getValue(), PersonalEventEnum.ADD.getDesc());
            }
            // 实际部门Id
            String depId = null;
            if (companyDepInfoDO != null && StringUtils.isNotBlank(empInfo.getDepName())) {
                depId = depNameIdMap.get(empInfo.getDepName());
                if (depId == null) {
                    // 公司级部门
                    String parentId = companyDepInfoDO.getId();
                    String[] split = empInfo.getDepName().split("/");
                    for (int i = 0; i < split.length; i++) {
                        // 下级部门
                        DepInfoDO depInfoDO = depInfoService.selectByNameAndLevel(split[i], i + 3, parentId, companyId, tokenUser);
                        if (depInfoDO == null) {
                            DepInfoAddDTO depInfoAddDTO = new DepInfoAddDTO();
                            depInfoAddDTO.setName(split[i]);
                            depInfoAddDTO.setLevel(i + 3);
                            depInfoAddDTO.setParentId(parentId);
                            depInfoAddDTO.setAddress("");
                            depInfoAddDTO.setSort(1);
                            depInfoAddDTO.setCompanyId(companyId);
                            DepInfoVO save = depInfoService.save(depInfoAddDTO, tokenUser);
                            depInfoDO = save.to(DepInfoDO.class);
                        }
                        parentId = depInfoDO.getId();
                        // 最后一次的Id为最终Id
                        depId = parentId;
                        // 新建部门放入map(key为全路径 下次同名不需要重新查询 节约时间)
                        depNameIdMap.put(empInfo.getDepName(), depId);
                    }
                }
            }
            if (depId != null) {
                publishEmpDep(Collections.singletonList(depId), companyId, empInfo.getId(), tokenUser);
            }

            List<String> positionIdList = new ArrayList<>();
            if (positionInfoDO != null && StringUtils.isNotBlank(empInfo.getPositionName())) {
                // 分类名称
                String typeName;
                // 岗位名称
                String name;
                if (empInfo.getPositionName().contains("/")) {
                    // 含有分类
                    String[] split = empInfo.getPositionName().split("/");
                    typeName = split[0];
                    name = split[1];
                } else {
                    // 不含分类
                    typeName = "默认类型";
                    name = empInfo.getPositionName();
                }
                // 岗位类型
                String parentId = positionInfoDO.getId();
                PositionInfoDO typePositionInfoDO = positionInfoService
                        .selectByNameAndLevel(typeName, 2, parentId, companyId, tokenUser);
                if (typePositionInfoDO == null) {
                    PositionInfoAddDTO positionInfoAddDTO = new PositionInfoAddDTO();
                    positionInfoAddDTO.setCompanyId(companyId);
                    positionInfoAddDTO.setLevel(2);
                    positionInfoAddDTO.setName(typeName);
                    positionInfoAddDTO.setParentId(parentId);
                    positionInfoAddDTO.setSort(0);
                    positionInfoAddDTO.setType(2);
                    PositionInfoVO save = positionInfoService.save(positionInfoAddDTO, tokenUser);
                    typePositionInfoDO = save.to(PositionInfoDO.class);
                }
                // 岗位
                PositionInfoDO onePositionInfoDO = positionInfoService
                        .selectByNameAndLevel(name, 3, typePositionInfoDO.getId(), companyId, tokenUser);
                if (onePositionInfoDO == null) {
                    PositionInfoAddDTO positionInfoAddDTO = new PositionInfoAddDTO();
                    positionInfoAddDTO.setCompanyId(companyId);
                    positionInfoAddDTO.setLevel(3);
                    positionInfoAddDTO.setName(name);
                    positionInfoAddDTO.setParentId(typePositionInfoDO.getId());
                    positionInfoAddDTO.setSort(0);
                    positionInfoAddDTO.setType(1);
                    PositionInfoVO save = positionInfoService.save(positionInfoAddDTO, tokenUser);
                    onePositionInfoDO = save.to(PositionInfoDO.class);
                }
                positionIdList.add(onePositionInfoDO.getId());
            }
            if (!CollectionUtils.isEmpty(positionIdList)) {
                publishEmpPosition(positionIdList, companyId, empInfo.getId(), tokenUser);
            }
            // 合同类型未填写 默认电子合同
            if (StringUtils.isBlank(empInfo.getEmpContractType()) && (null != empInfo.getContractStartDate()
                    || null != empInfo.getContractEndDate() || null != empInfo.getContractExpire()
                    || null != empInfo.getContractsRemark() || null != empInfo.getContractExpireStr())) {
                empInfo.setEmpContractType("电子合同");
            }
            if ("纸质合同".equals(empInfo.getEmpContractType())) {
                List<EmpPaperContractDTO> empPaperContractList = new ArrayList<>();
                EmpPaperContractDTO empPaperContractDTO = new EmpPaperContractDTO();
                empPaperContractDTO.setName(empInfo.getContractsName());
                empPaperContractDTO.setType(empInfo.getFileTypeValue());
                empPaperContractDTO.setStartTime(empInfo.getContractStartDate());
                empPaperContractDTO.setEndTime(empInfo.getContractEndDate());
                empPaperContractDTO.setTimeLimit(empInfo.getContractExpire());
                empPaperContractDTO.setRemarks(empInfo.getContractsRemark());
                empPaperContractDTO.setNumber(empInfo.getContractsNumber());
                empPaperContractDTO.setCompanyName(empInfo.getCompanyName());
                empPaperContractDTO.setSubscribeTime(empInfo.getSubscribeTime());
                empPaperContractDTO.setStatus(empInfo.getPaperContractsStatus());
                empPaperContractDTO.setCompanyId(companyId);
                if (StringUtils.isNotBlank(empInfo.getContractExpireStr())) {
                    try {
                        if (empInfo.getContractExpireStr().contains("年")) {
                            empPaperContractDTO.setTimeLimit(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("年", "")));
                            empPaperContractDTO.setTimeLimitType(1);
                        } else if (empInfo.getContractExpireStr().contains("月")) {
                            empPaperContractDTO.setTimeLimit(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("月", "")));
                            empPaperContractDTO.setTimeLimitType(2);
                        } else if (empInfo.getContractExpireStr().contains("日")) {
                            empPaperContractDTO.setTimeLimit(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("日", "")));
                            empPaperContractDTO.setTimeLimitType(3);
                        } else {
                            log.error("花名册批量导入员工：" + empInfo.getName() + "的纸质合同的合同期限有误："
                                    + empInfo.getContractExpireStr());
                        }
                    } catch (NumberFormatException e) {
                        log.error("花名册批量导入员工：" + empInfo.getName() + "的纸质合同的合同期限有误："
                                + empInfo.getContractExpireStr());
                    }
                }
                empPaperContractList.add(empPaperContractDTO);
                publishEmpPaperContractList(empPaperContractList, companyId, empInfo.getId(), tokenUser);
            } else if ("电子合同".equals(empInfo.getEmpContractType())) {
                List<EmpContractDTO> empContractList = new ArrayList<>();
                EmpContractDTO empContractDTO = new EmpContractDTO();
                empContractDTO.setName(empInfo.getContractsName());
                empContractDTO.setType(empInfo.getFileTypeValue());
                empContractDTO.setStartTime(empInfo.getContractStartDate());
                empContractDTO.setEndTime(empInfo.getContractEndDate());
                empContractDTO.setTermYear(empInfo.getContractExpire());
                empContractDTO.setRemake(empInfo.getContractsRemark());
                empContractDTO.setCompanyId(companyId);
                if (StringUtils.isNotBlank(empInfo.getContractExpireStr())) {
                    try {
                        if (empInfo.getContractExpireStr().contains("年")) {
                            empContractDTO.setTermYear(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("年", "")));
                        } else if (empInfo.getContractExpireStr().contains("月")) {
                            empContractDTO.setTermMonth(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("月", "")));
                        } else if (empInfo.getContractExpireStr().contains("日")) {
                            empContractDTO.setTermDay(Integer
                                    .parseInt(empInfo.getContractExpireStr().replace("日", "")));
                        } else {
                            log.error("花名册批量导入员工：" + empInfo.getName() + "的电子合同的合同期限有误："
                                    + empInfo.getContractExpireStr());
                        }
                    } catch (NumberFormatException e) {
                        log.error("花名册批量导入员工：" + empInfo.getName() + "的电子合同的合同期限有误："
                                + empInfo.getContractExpireStr());
                    }
                }
                empContractList.add(empContractDTO);
                publishEmpContractList(empContractList, companyId, empInfo.getId(), tokenUser);
            }
            // 只有新增才会新建一条学历，修改不处理
            if (StrKit.isNotEmpty(empInfo.getEducation()) && isAdd) {
                EducationLevelEnum educationLevelEnum = EducationLevelEnum.findByDesc(empInfo.getEducation());
                if (educationLevelEnum != null) {
                    EmpEducationAddDTO empEducationAddDTO = new EmpEducationAddDTO();
                    empEducationAddDTO.setEmpId(empInfo.getId());
                    empEducationAddDTO.setCompanyId(companyId);
                    empEducationAddDTO.setEducation(educationLevelEnum.getValue());
                    empEducationService.save(empEducationAddDTO, tokenUser);
                }
            }
            // 自定义字段
            if (empInfo.getFieldNameMap() != null) {
                List<EmpAdditionalFieldsAddDTO> empAdditionalFieldsAddDTOList = new ArrayList<>();
                // 导入自定义字段
                for (String filedName : empInfo.getFieldNameMap().keySet()) {
                    List<CompanyAdditionalFieldsDO> companyAdditionalFieldsDOList
                            = companyAdditionalFieldsService.selectByModuleAndFiledName(null, filedName, companyId);
                    // 匹配到公司的自定义字段
                    if (!CollectionUtils.isEmpty(companyAdditionalFieldsDOList)) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO = companyAdditionalFieldsDOList.get(0);
                        String content = empInfo.getFieldNameMap().get(filedName);
                        // 如果是地区类型，要转为code
                        if (Objects.equals(FIELD_TYPE_AREA, companyAdditionalFieldsDO.getFieldType())) {
                            String areaCode = FormatUtils.cityNameToAreaCode(content, areaList);
                            // 如果识别不了自定义地区字段，不进数据库
                            if (StrKit.isNotEmpty(areaCode)) {
                                content = areaCode;
                            } else {
                                continue;
                            }
                        }
                        EmpAdditionalFieldsAddDTO empAdditionalFieldsAddDTO = new EmpAdditionalFieldsAddDTO();
                        empAdditionalFieldsAddDTO.setCompanyId(companyId);
                        empAdditionalFieldsAddDTO.setEmpId(empInfo.getId());
                        empAdditionalFieldsAddDTO.setFieldId(companyAdditionalFieldsDO.getId());
                        empAdditionalFieldsAddDTO.setModuleCode(companyAdditionalFieldsDO.getModuleCode());
                        empAdditionalFieldsAddDTO.setContent(content);
                        empAdditionalFieldsAddDTOList.add(empAdditionalFieldsAddDTO);
                    }
                }
                // 自定义字段 按ModuleCode分组
                Map<String, List<EmpAdditionalFieldsAddDTO>> moduleCodeListMap = empAdditionalFieldsAddDTOList
                        .parallelStream().collect(Collectors.groupingBy(EmpAdditionalFieldsAddDTO::getModuleCode));
                for (String moduleCode : moduleCodeListMap.keySet()) {
                    empAdditionalFieldsService.savePreDelete(empInfo.getId(), companyId, moduleCode
                            , moduleCodeListMap.get(moduleCode), tokenUser);
                }
            }
        }
        log.info("花名册导入数据,其他操作结束,时间戳:{}", System.currentTimeMillis());
    }

    /**
     * 修改预登记渠道
     *
     * @param empInfoDO 员工信息
     * @param tokenUser 当前用户
     */
    private void updateCheckInChannel(EmpInfoDO empInfoDO, TokenUser tokenUser) {
        try {
            if (StringUtils.isEmpty(empInfoDO.getChannelId())) {
                return;
            }
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
            if (checkInPeopleDO == null) {
                return;
            }
            CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = checkInPeopleDO.to(CheckInPeopleUpdateDTO.class);
            checkInPeopleUpdateDTO.setChannelId(empInfoDO.getChannelId());
            checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
        } catch (Exception e) {
            log.error("花名册导入预登记渠道修改错误，错误数据：{}", JSONObject.toJSONString(empInfoDO));
        }
    }

    @Override
    public String getAreaInfoByName(List<AreaReduceVO> areaList, String name) {
        if (StringUtils.isEmpty(name)) {
            return null;
        }
        // 员工所属地区
        AreaReduceVO areaReduce = adminProviderService.getAreaByName(areaList, name);
        if (Objects.nonNull(areaReduce)) {
            // 放入员工中
            return areaReduce.getId() == null ? null : areaReduce.getId().toString();
        }
        return null;
    }

    @Override
    public Page<EmpInfoListVO> pageOnJobEmpList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        long startTime = System.currentTimeMillis();
        Example example = buildExample(empInfoQuery, tokenUser);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        Page<EmpInfoListVO> returnPage = getPage(empInfoQuery, example, tokenUser);
        long l1 = System.currentTimeMillis();
        log.info("==========花名册检索构建page对象,耗时{}ms:", (l1 - startTime));
        if (returnPage == null) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
        if (CollectionUtils.isEmpty(returnPage.getEntities())) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
//        List<String> empIdList = returnPage.getEntities().parallelStream()
//                .map(EmpInfoListVO::getId).collect(Collectors.toList());


        // 员工id-员工未完善信息
//        Map<String, String> empIdNotCompleteMap = listNotComplete(empInfoQuery.getCompanyId(), empIdList, tokenUser);
//        long l2 = System.currentTimeMillis();
//        log.info("花名册查询员工未完善信息，耗时：{}ms", (l2 - l1));
//
//        returnPage.getEntities().forEach(empInfoListVO -> {
//            String needComplete = empIdNotCompleteMap.get(empInfoListVO.getId());
//            Boolean isImprove = empInfoListVO.getIsImprove();
//            if (StringUtils.isBlank(needComplete)) {
//                // 如果必填字段为空,说明这人把该填的都填了
//                // 并且这个人的必填状态是false,这个时候需要在用工档案添加一条此员工已完善信息的记录
//                if (!isImprove) {
//                    PersonalEventDO personalEventDO = new PersonalEventDO();
//                    // 是否自动生成
//                    personalEventDO.setIfAuto(true);
//                    // 事件时间
//                    personalEventDO.setEventTime(new Date());
//                    // 事件类型(个人信息已完善)
//                    personalEventDO.setEventType(PersonalEventEnum.DETAILS_INFO.getValue());
//                    // 备注
//                    personalEventDO.setDescription("个人信息已完善");
//                    // 事件名称
//                    personalEventDO.setEventName(PersonalEventEnum.DETAILS_INFO.getDesc());
//                    personalEventDO.setUserId(empInfoListVO.getUserId());
//                    personalEventDO.setCompanyId(empInfoListVO.getCompanyId());
//                    personalEventDO.setEmpId(empInfoListVO.getId());
//                    personalEventService.save(personalEventDO, tokenUser.getSiteId(), tokenUser.getUserId());
//                }
//                // 已完善
//                empInfoListVO.setIsImprove(true);
//            } else {
//                // 未完善
//                empInfoListVO.setIsImprove(false);
//                empInfoListVO.setNeedComplete(needComplete);
//            }
//            if (!isImprove.equals(empInfoListVO.getIsImprove())) {
//                // 必填项全都填满 修改 是否完善员工信息 为 1：完善
//                EmpInfoDO empInfoDO = new EmpInfoDO();
//                empInfoDO.setId(empInfoListVO.getId());
//                empInfoDO.setIsImprove(empInfoListVO.getIsImprove());
//                updateByIdSelective(empInfoDO, empInfoListVO.getSiteId(), tokenUser.getUserId());
//            }
//        });
        long l3 = System.currentTimeMillis();
        log.info("花名册查询循环赋值，耗时：{}ms", (l3 - l1));

        //查询公司所有自定义字段
        List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList =
                companyAdditionalFieldsService.selectOpenByCompanyId(empInfoQuery.getCompanyId(), tokenUser.getSiteId());
        //自定义字段属性赋值
        customAttributeFill(returnPage.getEntities(), companyAdditionalFieldsListVOList);
        long l4 = System.currentTimeMillis();
        log.info("花名册查询自定义字段赋值，耗时：{}ms", (l4 - l3));

        //调用给其他属性赋值方法
        batchOtherHeaderAssignment(returnPage.getEntities(), tokenUser);
        long l5 = System.currentTimeMillis();
        log.info("花名册查询给其他属性赋值，耗时：{}ms", (l5 - l4));
        return returnPage;
    }

    @Transactional
    @Override
    public void empCompleteInfo(List<String> empIdList, TokenUser tokenUser) {
        EmpInfoDO tempEmpInfoDO = this.selectById(empIdList.get(0));
        Map<String, String> empIdNotCompleteMap = listNotComplete(tempEmpInfoDO.getCompanyId(), empIdList, tokenUser);
        for (String empId : empIdList) {
            EmpInfoDO empInfoDO = this.selectById(empId);
            String needComplete = empIdNotCompleteMap.get(empId);
            Boolean isImprove = empInfoDO.getIsImprove();
            log.info("检查员工必填字段是否已完善" + empInfoDO.getPhone() + " 必填字段： " + needComplete);
            if (StringUtils.isBlank(needComplete)) {
                // 如果必填字段为空,说明这人把该填的都填了
                // 并且这个人的必填状态是false,这个时候需要在用工档案添加一条此员工已完善信息的记录
                if (!isImprove) {
                    PersonalEventDO personalEventDO = new PersonalEventDO();
                    // 是否自动生成
                    personalEventDO.setIfAuto(true);
                    // 事件时间
                    personalEventDO.setEventTime(new Date());
                    // 事件类型(个人信息已完善)
                    personalEventDO.setEventType(PersonalEventEnum.DETAILS_INFO.getValue());
                    // 备注
                    personalEventDO.setDescription("个人信息已完善");
                    // 事件名称
                    personalEventDO.setEventName(PersonalEventEnum.DETAILS_INFO.getDesc());
                    personalEventDO.setUserId(empInfoDO.getUserId());
                    personalEventDO.setCompanyId(empInfoDO.getCompanyId());
                    personalEventDO.setEmpId(empInfoDO.getId());
                    personalEventService.save(personalEventDO, tokenUser.getSiteId(), tokenUser.getUserId());
                }
                EmpInfoDO param = new EmpInfoDO();
                param.setId(empInfoDO.getId());
                param.setIsImprove(true);
                updateByIdSelective(param, empInfoDO.getSiteId(), tokenUser.getUserId());
            } else {
                EmpInfoDO param = new EmpInfoDO();
                param.setId(empInfoDO.getId());
                param.setIsImprove(false);
                updateByIdSelective(param, empInfoDO.getSiteId(), tokenUser.getUserId());
            }
        }

    }

    /**
     * 员工自定义字段属性填充
     *
     * @param empInfoListVOList                 员工volist
     * @param companyAdditionalFieldsListVOList 自定义字段
     */
    private void customAttributeFill(List<EmpInfoListVO> empInfoListVOList, List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList) {
        if (CollectionUtils.isEmpty(companyAdditionalFieldsListVOList) || CollectionUtils.isEmpty(empInfoListVOList)) {
            return;
        }
        Map<Long, CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOMap = companyAdditionalFieldsListVOList.parallelStream().collect(Collectors.toMap(CompanyAdditionalFieldsListVO::getId, p -> p));
        TokenUser tokenUser = UserContext.getUser();
        List<AreaReduceVO> areaList = adminProviderService.listAllArea();
        List<String> empIdList = empInfoListVOList.parallelStream().map(EmpInfoListVO::getId).collect(Collectors.toList());
        //查询指定员工的自定义字段属性
        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empAdditionalFieldsService.selectByEmpIds(empIdList, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(empAdditionalFieldsDOList)) {
            return;
        }
        Map<String, List<EmpAdditionalFieldsDO>> empMap = empAdditionalFieldsDOList.parallelStream().collect(Collectors.groupingBy(EmpAdditionalFieldsDO::getEmpId));
        //属性填充
        empInfoListVOList.forEach(empInfoListVO -> {
            Map<String, String> data = new HashMap<>();
            for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO : companyAdditionalFieldsListVOList) {
                data.put(SafeKit.getString(companyAdditionalFieldsListVO.getId()), "");
            }
            if (empMap.containsKey(empInfoListVO.getId())) {
                List<EmpAdditionalFieldsDO> empAdditionalFieldsDOS = empMap.get(empInfoListVO.getId());
                empAdditionalFieldsDOS.forEach(empAdditionalFieldsDO -> {
                    if (data.containsKey(SafeKit.getString(empAdditionalFieldsDO.getFieldId())) && companyAdditionalFieldsListVOMap.containsKey(empAdditionalFieldsDO.getFieldId())) {
                        CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO = companyAdditionalFieldsListVOMap.get(empAdditionalFieldsDO.getFieldId());
                        // 地区信息
                        if (companyAdditionalFieldsListVO.getFieldType() == 6) {
                            empAdditionalFieldsDO.setContent(FormatUtils.getNameByCode(empAdditionalFieldsDO.getContent(), areaList, ",", "-", ""));
                        }
                        data.put(SafeKit.getString(empAdditionalFieldsDO.getFieldId()), empAdditionalFieldsDO.getContent());
                    }
                });
            }
            empInfoListVO.setData(data);
        });
    }


    @Override
    public Page<EmpInfoListVO> pageBaseOnJobEmpList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        return getPage(empInfoQuery, example, tokenUser);
    }

    /**
     * 处理返回page
     */
    private Page<EmpInfoListVO> getPage(EmpInfoQuery empInfoQuery, Example example, TokenUser tokenUser) {
        Page<EmpInfoListVO> returnPage = new Page<>();
        String companyId = empInfoQuery.getCompanyId();
        Integer pageNo = empInfoQuery.getPageNo();
        Integer pageSize = empInfoQuery.getPageSize();
        String tag = empInfoQuery.getTag();
        if (StrKit.isNotEmpty(tag)) {
            String[] array = tag.split(",");
            List<String> tagList = Arrays.asList(array);
            if (tagList.size() == 1) {
                String tagName = tagList.get(0);
                example.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                returnPage = pageVoByExample(example, companyId, pageNo, pageSize, tokenUser.getSiteId());
            } else {
                List<EmpInfoDO> empInfoDOList = new ArrayList<>();
                // 循环tag,全部检索
                for (String tagName : tagList) {
                    example.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                }
                empInfoDOList = empInfoDAO.selectByExample(example);
                if (!CollectionUtils.isEmpty(empInfoDOList)) {
                    List<EmpInfoListVO> empInfoList = empInfoDOList.stream()
                            .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class))
                            .collect(Collectors.toList());
                    // 增加部门和岗位信息
                    addDepAndPositionToEmpList(empInfoList, companyId, tokenUser.getSiteId());
                    returnPage = PageKit.startPage(empInfoList, pageNo, pageSize);
                } else {
                    return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
                }
            }
        } else {
            returnPage = pageVoByExample(example, companyId, pageNo, pageSize, tokenUser.getSiteId());
        }
        return returnPage;
    }

    @Override
    public List<EmpInfoDO> onJobEmpDOList(String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Page<EmpInfoListVO> selectIdNamePhoneOnJobEmpList(String companyId, String empNameOrPhone
            , Integer pageNo, Integer pageSize, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .andEqualTo("companyId", companyId);
        example.and()
                .orEqualTo("status", EmpInfoStatus.HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        if (StringUtils.isNotBlank(empNameOrPhone)) {
            example.and()
                    .orLike("name", "%" + empNameOrPhone + "%")
                    .orLike("phone", "%" + empNameOrPhone + "%");
        }
        example.selectProperties("id", "name", "phone");
        return empInfoDAO.selectPageByExample(example, pageNo, pageSize).to(EmpInfoListVO.class);
    }

    /**
     * 花名册动态表头,给 empInfo 对象以外的属性赋值
     */
    @Override
    public void otherHeaderAssignment(EmpInfoListVO empInfoListVO, TokenUser tokenUser) {
        // 赋值最高学历和学位
        Map<String, String> highestEducationAndDegree = empEducationService.selectHighestEducationAndDegree(empInfoListVO.getId());

        // 渠道赋值
        if (StrKit.isNotEmpty(empInfoListVO.getChannelId())) {
            ChannelVO channelVO = channelService.selectById(empInfoListVO.getChannelId(), tokenUser.getSiteId());
            if (Objects.nonNull(channelVO)) {
                empInfoListVO.setChannelName(channelVO.getName());
            }
        }

        // 学历赋值
        empInfoListVO.setHighestEducation(highestEducationAndDegree.get("education"));
        // 学位赋值
        empInfoListVO.setDegreeType(highestEducationAndDegree.get("degree"));
        // 毕业院校
        empInfoListVO.setGraCollege(highestEducationAndDegree.get("graCollege"));
        // 毕业专业
        empInfoListVO.setMajor(highestEducationAndDegree.get("major"));
        // 学习形式
        empInfoListVO.setTeaMethods(highestEducationAndDegree.get("teaMethods"));
        // 查询此人的紧急联系人列表,取第一个出去
        List<EmpContactsDO> empContactsDOList = empContactsService.listByEmpId(empInfoListVO.getId(), tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empContactsDOList)) {
            empInfoListVO.setContactsName(empContactsDOList.get(0).getName());
            empInfoListVO.setContactsPhone(empContactsDOList.get(0).getPhone());
        } else {
            // 没有紧急联系人,就赋空值
            empInfoListVO.setContactsName("");
            empInfoListVO.setContactsPhone("");
        }
        // 赋值合同信息
        ContractDO contractDO = contractProviderService
                .selectAllSignedRecording(empInfoListVO.getUserId(), empInfoListVO.getCompanyId(), empInfoListVO.getId(), tokenUser);
        if (null != contractDO) {
            // 赋值合同类型
            empInfoListVO.setContractType(contractDO.getFileType());
            empInfoListVO.setContractName(contractDO.getName());
            // 赋值合同开始时间
            empInfoListVO.setContractStartTime(contractDO.getPublishDate());
            // 赋值合同结束时间
            empInfoListVO.setContractEndTime(contractDO.getEndDate());
            // 赋值合同状态
            empInfoListVO.setContractsStatus(contractDO.getStatus());
            // 赋值合同期限
            if (contractDO.getDateline() != null) {
                if (contractDO.getDateline() % 12 == 0) {
                    empInfoListVO.setContactsTerm(contractDO.getDateline() / 12 + "年");
                } else {
                    empInfoListVO.setContactsTerm(contractDO.getDateline().toString() + "个月");
                }
            }
        } else {
            empInfoListVO.setContractsStatus(ContractsStatus.NOT_INITIATED.getValue());
        }
        // 添加自定义字段的值
        Map<String, String> customFields = new HashMap<>(8);
        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empAdditionalFieldsService
                .selectByEmpId(empInfoListVO.getId(), tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empAdditionalFieldsDOList)) {
            for (EmpAdditionalFieldsDO empAdditionalFieldsDO : empAdditionalFieldsDOList) {
                String content = empAdditionalFieldsDO.getContent();
                CompanyAdditionalFieldsDO companyAdditionalFieldsDO = companyAdditionalFieldsService
                        .selectByIdNoSite(empAdditionalFieldsDO.getFieldId());
                if (Objects.isNull(companyAdditionalFieldsDO)) {
                    continue;
                }
                String fieldName = companyAdditionalFieldsDO.getFieldName();
                customFields.put(fieldName, content);
            }
        }
        empInfoListVO.setCustomFields(customFields);
    }

    @Override
    public EmpInfoCurrentPositionVO getEmpCurrentPosition(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        if (StringUtils.isEmpty(empInfoQuery.getEmpId())) {
            throw new ParamException("输入的员工id不能为空");
        }
        if (empInfoQuery.getQueryType() == null) {
            empInfoQuery.setQueryType(1);
        }
        EmpInfoCurrentPositionVO empInfoCurrentPositionVO = new EmpInfoCurrentPositionVO();
        Integer currentPosition = 0;
        Integer allNumber = 0;
        EmpInfoListVO lastEmpInfoListVO = new EmpInfoListVO();
        EmpInfoListVO nextEmpInfoListVO = new EmpInfoListVO();
        if (empInfoQuery.getQueryType() != 3) {
            List<EmpInfoListVO> empInfoListVOList = new ArrayList<>();
            if (empInfoQuery.getQueryType() == 1) {
                empInfoListVOList = listOnJobEmpListWithoutExtend(empInfoQuery, tokenUser);
            } else if (empInfoQuery.getQueryType() == 2) {
                empInfoListVOList = selectEmpInfoPendingRelationList(empInfoQuery, tokenUser);
            } else if (empInfoQuery.getQueryType() == 4) {
                empInfoListVOList = selectEmpInfoToFormalRelationList(empInfoQuery, tokenUser);
            } else if (empInfoQuery.getQueryType() == 5) {
                empInfoListVOList = selectEmpInfoOnJobRelationList(empInfoQuery, tokenUser);
            } else if (empInfoQuery.getQueryType() == 6) {
                EmpChangesQuery empChangesQuery = new EmpChangesQuery();
                empChangesQuery.setCompanyId(empInfoQuery.getCompanyId());
                List<EmpChangesRelationVO> list = empChangesService.empResignedList(empChangesQuery, tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(list)) {
                    for (EmpChangesRelationVO item : list) {
                        EmpInfoListVO empInfoListVO = new EmpInfoListVO();
                        empInfoListVO.setName(item.getEmpName());
                        empInfoListVO.setId(item.getEmpId());
                        empInfoListVOList.add(empInfoListVO);
                    }
                }
            } else {
                EmpChangesQuery empChangesQuery = new EmpChangesQuery();
                empChangesQuery.setCompanyId(empInfoQuery.getCompanyId());
                List<EmpChangesRelationVO> list = empChangesService.empTransferList(empChangesQuery, tokenUser.getSiteId());
                if (!CollectionUtils.isEmpty(list)) {
                    for (EmpChangesRelationVO item : list) {
                        EmpInfoListVO empInfoListVO = new EmpInfoListVO();
                        empInfoListVO.setName(item.getEmpName());
                        empInfoListVO.setId(item.getEmpId());
                        empInfoListVOList.add(empInfoListVO);
                    }
                }
            }

            if (!CollectionUtils.isEmpty(empInfoListVOList)) {
                allNumber = empInfoListVOList.size();
                for (int i = 0; i < allNumber; i++) {
                    if (empInfoListVOList.get(i).getId().equals(empInfoQuery.getEmpId())) {
                        currentPosition = i + 1;
                        break;
                    }
                }
                if (currentPosition != 0) {
                    if (currentPosition != 1) {
                        lastEmpInfoListVO = empInfoListVOList.get(currentPosition - 2);
                    }
                    if (!currentPosition.equals(allNumber)) {
                        nextEmpInfoListVO = empInfoListVOList.get(currentPosition);
                    }
                }
            }
        } else {
            empInfoQuery.setCompanyId(null);
            List<StatisticsEmpInfoVO> statisticsEmpInfoVOList
                    = statisticsPageService.selectAllStaffList(empInfoQuery.to(EmpBySiteQuery.class), tokenUser);
            if (!CollectionUtils.isEmpty(statisticsEmpInfoVOList)) {
                allNumber = statisticsEmpInfoVOList.size();
                for (int i = 0; i < allNumber; i++) {
                    if (statisticsEmpInfoVOList.get(i).getId().equals(empInfoQuery.getEmpId())) {
                        currentPosition = i + 1;
                        break;
                    }
                }
                if (currentPosition != 0) {
                    if (currentPosition != 1) {
                        lastEmpInfoListVO = statisticsEmpInfoVOList.get(currentPosition - 2).to(EmpInfoListVO.class);
                    }
                    if (!currentPosition.equals(allNumber)) {
                        nextEmpInfoListVO = statisticsEmpInfoVOList.get(currentPosition).to(EmpInfoListVO.class);
                    }
                }
            }

        }

        empInfoCurrentPositionVO.setAllNumber(allNumber);
        empInfoCurrentPositionVO.setCurrentPosition(currentPosition);
        empInfoCurrentPositionVO.setLastEmpInfoListVO(lastEmpInfoListVO);
        empInfoCurrentPositionVO.setNextEmpInfoListVO(nextEmpInfoListVO);
        return empInfoCurrentPositionVO;
    }

    @Override
    public String notComplete(String companyId, String empId, TokenUser tokenUser) {
        String needComplete = "";
        CompanyNecessaryFieldQuery companyNecessaryFieldQuery = new CompanyNecessaryFieldQuery();
        companyNecessaryFieldQuery.setCompanyId(companyId);
        companyNecessaryFieldQuery.setEmpInfoId(empId);
        long l1 = System.currentTimeMillis();
        CompanyFieldAndValueListVO companyFieldAndValueListVO =
                companyNecessaryFieldService.listAllForApp(companyNecessaryFieldQuery, tokenUser);
        long l2 = System.currentTimeMillis();
        log.info("app端查询公司员工必填字段信息及其具体的值，耗时：{}ms", (l2 - l1));
        String[] types = {"basic", "empFamily", "contact", "empWork", "empEducation", "empContacts", "empTrain"
                , "annex", "socAndPf", "bank", "archive", "leaveOffice"};
        //公司员工基本信息
        for (String type : types) {
            String need = companyNecessaryFieldService.findNotCompleteUpdate(companyFieldAndValueListVO, type, companyId, tokenUser);
            String otherNeed = companyNecessaryFieldService.findNotCompleteAdditional(companyFieldAndValueListVO, type);
            if (!StringUtils.isEmpty(need)) {
                if ("".equals(needComplete)) {
                    needComplete = need;
                } else {
                    needComplete = needComplete + "," + need;
                }
            }
            if (!StringUtils.isEmpty(otherNeed)) {
                if ("".equals(needComplete)) {
                    needComplete = otherNeed;
                } else {
                    needComplete = needComplete + "," + otherNeed;
                }
            }
        }
        long l3 = System.currentTimeMillis();
        log.info("查询公司员工基本信息，耗时：{}ms", (l3 - l2));
        //公司员工基本额外信息
        //公司员工联系人所需额外信息
        //司员工附件所需额外信息
        //公司员工员工档案资料所需额外信息
        //公司员工离职资料附件所需额外信息

        return needComplete;
    }

    @Override
    public Map<String, String> listNotComplete(String companyId, List<String> empIdList, TokenUser tokenUser) {
        CompanyNecessaryFieldQuery companyNecessaryFieldQuery = new CompanyNecessaryFieldQuery();
        companyNecessaryFieldQuery.setCompanyId(companyId);
        long l1 = System.currentTimeMillis();
        List<CompanyFieldAndValueListVO> valueListVOS = companyNecessaryFieldService.listAllForApp2(companyNecessaryFieldQuery, empIdList, tokenUser);
        long l2 = System.currentTimeMillis();
        log.info("app端查询公司员工必填字段信息及其具体的值，耗时：{}ms", (l2 - l1));
        String[] types = {"basic", "empFamily", "contact", "empWork", "empEducation", "empContacts", "empTrain"
                , "annex", "socAndPf", "bank", "archive", "leaveOffice"};
        Map<String, String> notCompleteMap = new HashMap<>(16);
        for (CompanyFieldAndValueListVO companyFieldAndValueListVO : valueListVOS) {
            String needComplete = "";
            //公司员工基本信息
            for (String type : types) {
                String need = companyNecessaryFieldService.findNotCompleteUpdate(companyFieldAndValueListVO, type, companyId, tokenUser);
                String otherNeed = companyNecessaryFieldService.findNotCompleteAdditional(companyFieldAndValueListVO, type);
                log.info("员工：{}，need：{}，otherNeed：{}", companyFieldAndValueListVO.getEmpId(), need, otherNeed);
                if (!StringUtils.isEmpty(need)) {
                    if ("".equals(needComplete)) {
                        needComplete = need;
                    } else {
                        needComplete = needComplete + "," + need;
                    }
                }
                if (!StringUtils.isEmpty(otherNeed)) {
                    if ("".equals(needComplete)) {
                        needComplete = otherNeed;
                    } else {
                        needComplete = needComplete + "," + otherNeed;
                    }
                }
            }
            notCompleteMap.put(companyFieldAndValueListVO.getEmpId(), needComplete);
        }
        long l3 = System.currentTimeMillis();
        log.info("查询公司员工基本信息，耗时：{}ms", (l3 - l2));
        //公司员工基本额外信息
        //公司员工联系人所需额外信息
        //司员工附件所需额外信息
        //公司员工员工档案资料所需额外信息
        //公司员工离职资料附件所需额外信息

        return notCompleteMap;
    }

    @Override
    public List<EmpInfoListVO> listOnJobEmpList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);

        // 未指定导出员工状态 默认导出在职员工
        if (empInfoQuery.getStatus() == null) {
            // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
            example.and()
                    .orEqualTo("status", HAS_ENTRY.getValue())
                    .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        }
        if (StrKit.isNotEmpty(empInfoQuery.getNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + empInfoQuery.getNameOrPhone() + "%");
        }

        List<EmpInfoListVO> empInfoList = new ArrayList<>();
        long l1 = System.currentTimeMillis();
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            String[] array = empInfoQuery.getTag().split(",");
            List<String> tagList = Arrays.asList(array);
            if (tagList.size() == 1) {
                String tagName = tagList.get(0);
                example.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                empInfoList = listVoRelationByExample(empInfoQuery.getCompanyId(), example, tokenUser.getSiteId());
            } else {
                // 如果不带标签的检索都查不到人,就没必要检索标签了
                List<EmpInfoListVO> empInfoListVOS = listVoRelationByExample(empInfoQuery.getCompanyId(), example, tokenUser.getSiteId());
                if (CollectionUtils.isEmpty(empInfoListVOS)) {
                    return new ArrayList<>();
                }
                for (String tagName : tagList) {
                    Example example1 = ExampleKit.copyExample(example, EmpInfoDO.class);
                    example1.and().andCondition("FIND_IN_SET('" + tagName + "' , tag)");
                    List<EmpInfoListVO> empInfoListItem = listVoRelationByExample(empInfoQuery.getCompanyId(), example1, tokenUser.getSiteId());
                    empInfoList.addAll(empInfoListItem);
                }
                // 去重
                empInfoList = empInfoList.stream().filter(StreamKit.distinctByKey(EmpInfoListVO::getId)).collect(Collectors.toList());

            }
        } else {
            empInfoList = listVoRelationByExample(empInfoQuery.getCompanyId(), example, tokenUser.getSiteId());
        }
        log.info("花名册导出标签检索耗时：{}ms", (System.currentTimeMillis() - l1));
        long l3 = System.currentTimeMillis();
        batchOtherHeaderAssignment(empInfoList, tokenUser);
        log.info("花名册动态表头,给 empInfo 对象以外的属性赋值,耗时：{}ms", (System.currentTimeMillis() - l3));
        // 勾选指定员工参数
        if (!CollectionUtils.isEmpty(empInfoList) && !CollectionUtils.isEmpty(empInfoQuery.getEmpIdList())) {
            empInfoList = empInfoList.stream()
                    .filter(empInfo -> empInfoQuery.getEmpIdList().contains(empInfo.getId()))
                    .collect(Collectors.toList());
        }

        return empInfoList;
    }

    @Override
    public void batchOtherHeaderAssignment(List<EmpInfoListVO> empInfoList, TokenUser tokenUser) {
        // 员工id集合
        List<String> empIdList = empInfoList.parallelStream().map(EmpInfoListVO::getId).collect(Collectors.toList());
        // 用工单位id
        String companyId = empInfoList.get(0).getCompanyId();

        // **********查询渠道信息**********
        // 渠道id集合
        List<String> channelIdList = empInfoList.parallelStream().map(EmpInfoListVO::getChannelId)
                .filter(StrKit::isNotEmpty).collect(Collectors.toList());
        List<ChannelVO> channelVOS = channelService.selectByIds(channelIdList, tokenUser.getSiteId());
        // 渠道id-名称 Map
        Map<String, String> channelIdNameMap = channelVOS.parallelStream()
                .collect(Collectors.toMap(ChannelVO::getId, ChannelVO::getName));
        // 员工id-教育经历 Map
        List<EmpEducationMapVO> empIdEducationMapList = empEducationService.listHighestEducationAndDegree(empIdList);
        Map<String, EmpEducationMapVO> empIdEducationMap = empIdEducationMapList.parallelStream()
                .collect(Collectors.toMap(EmpEducationMapVO::getEmpId, v -> v));

        // **********查询合同信息**********
        // 查询花名册电子合同
        List<EmpContractDO> empContractDOS = empContractService.selectByCompanyIdAndEmpIds(companyId, empIdList);
        // 员工-电子合同 Map
        Map<String, List<EmpContractDO>> empIdContractDOS = empContractDOS.parallelStream()
                .sorted(Comparator.comparing(EmpContractDO::getGmtCreate).reversed())
                .collect(Collectors.groupingBy(EmpContractDO::getEmpId, Collectors.toList()));
        // 查询花名册纸质合同
        List<EmpPaperContractDO> empPaperContractDOS = empPaperContractService
                .listContractByEmpIdList(companyId, empIdList, tokenUser);
        // 员工-纸质合同 Map
        LinkedHashMap<String, List<EmpPaperContractDO>> empIdPaperContractDOS = empPaperContractDOS.parallelStream()
                .sorted(Comparator.comparing(EmpPaperContractDO::getGmtCreate).reversed())
                .collect(Collectors.groupingBy(EmpPaperContractDO::getEmpId, LinkedHashMap::new, Collectors.toList()));

        // **********查询联系人信息，取创建时间最早的一条**********
        // 查询所有联系人信息
        List<EmpContactsDO> empContactsDOS = empContactsService.listByEmpIdList(empIdList, tokenUser);
        // 根据员工id分组
        Map<String, List<EmpContactsDO>> empIdContactsGroup = empContactsDOS.parallelStream().collect(Collectors.groupingBy(EmpContactsDO::getEmpId));

        // **********处理数据**********
        empInfoList.forEach(empInfoListVO -> {
            String empId = empInfoListVO.getId();
            EmpEducationMapVO empEducationMapVO = empIdEducationMap.get(empId);
            // 赋值最高学历和学位
            if (Objects.nonNull(empEducationMapVO)) {
                Map<String, String> highestEducationAndDegree = empEducationMapVO.getEmpEducationMap();
                // 学历赋值
                empInfoListVO.setHighestEducation(highestEducationAndDegree.get("education"));
                // 学位赋值
                empInfoListVO.setDegreeType(highestEducationAndDegree.get("degree"));
                // 毕业院校
                empInfoListVO.setGraCollege(highestEducationAndDegree.get("graCollege"));
                // 毕业专业
                empInfoListVO.setMajor(highestEducationAndDegree.get("major"));
                // 学习形式
                empInfoListVO.setTeaMethods(highestEducationAndDegree.get("teaMethods"));
            }
            String channelId = empInfoListVO.getChannelId();
            if (StrKit.isNotEmpty(channelId)) {
                String channelName = channelIdNameMap.get(channelId);
                empInfoListVO.setChannelName(channelName);
            }
            // 合同字段赋值
            List<EmpContractDO> contractDOS = empIdContractDOS.get(empId);
            List<EmpPaperContractDO> paperContractDOS = empIdPaperContractDOS.get(empId);
            setContractInfo(empInfoListVO, contractDOS, paperContractDOS);
            // 联系人信息赋值
            List<EmpContactsDO> contactsDOS = empIdContactsGroup.get(empId);
            if (!CollectionUtils.isEmpty(contactsDOS)) {
                // 取创建时间最早的一条
                EmpContactsDO empContactsDO = contactsDOS.stream()
                        .sorted(Comparator.comparing(EmpContactsDO::getGmtCreate)).collect(Collectors.toList()).get(0);
                empInfoListVO.setContactsName(empContactsDO.getName());
                empInfoListVO.setContactsPhone(empContactsDO.getPhone());
                empInfoListVO.setContactsRelation(empContactsDO.getRelation());
                empInfoListVO.setContactsAddress(empContactsDO.getAddress());
            }
        });
    }

    /**
     * 写入员工合同信息，花名册电子合同+纸质合同，合并取最新的一条
     * 产品要求的花名册合同信息展示电子合同+纸质合同，包含：合同开始时间，合同结束时间，合同期限，合同类型
     *
     * @param empInfoListVO       员工信息
     * @param empContractDOS      花名册电子合同
     * @param empPaperContractDOS 花名册纸质合同
     */
    private void setContractInfo(EmpInfoListVO empInfoListVO, List<EmpContractDO> empContractDOS,
                                 List<EmpPaperContractDO> empPaperContractDOS) {
        if (CollectionUtils.isEmpty(empContractDOS) && CollectionUtils.isEmpty(empPaperContractDOS)) {
            return;
        }
        List<ContractDataVO> contractListSort = getContractListSort(empContractDOS, empPaperContractDOS);
        if (CollectionUtils.isEmpty(contractListSort)) {
            return;
        }
        ContractDataVO contractDataVO = contractListSort.get(0);
        // 赋值合同类型
        empInfoListVO.setContractType(contractDataVO.getFileType());
        empInfoListVO.setContractName(contractDataVO.getName());
        // 赋值合同开始时间
        empInfoListVO.setContractStartTime(contractDataVO.getStartDate());
        // 赋值合同结束时间
        empInfoListVO.setContractEndTime(contractDataVO.getEndDate());

        // 统一处理为月份
        int month = contractDataVO.getDateline();
        if (month % 12 == 0) {
            empInfoListVO.setContactsTerm(month / 12 + "年");
        } else {
            empInfoListVO.setContactsTerm(month + "个月");
        }
    }

    /**
     * 将花名册电子合同，花名册纸质合同处理为统一格式并排序
     * 规则：开始时间最近的，开始时间相同取创建时间最近的
     *
     * @param empContractDOS      花名册电子合同
     * @param empPaperContractDOS 花名册纸质合同
     * @return 合同排序
     */
    private List<ContractDataVO> getContractListSort(List<EmpContractDO> empContractDOS,
                                                     List<EmpPaperContractDO> empPaperContractDOS) {
        // 花名册电子合同转为合同
        List<ContractDataVO> contractDataVOS = empContractToContractList(empContractDOS);
        // 花名册纸质合同转为合同
        List<ContractDataVO> contractDOS1 = empPaperContractToContractList(empPaperContractDOS);
        // 合并
        contractDataVOS.addAll(contractDOS1);
        if (CollectionUtils.isEmpty(contractDataVOS)) {
            return new ArrayList<>();
        }
        List<ContractDataVO> dataVOList = contractDataVOS.stream()
                .filter(contractDataVO -> StrKit.isNotEmpty(contractDataVO.getStartDate()))
                .sorted(Comparator.comparing(ContractDataVO::getStartDate, Comparator.reverseOrder())
                        .thenComparing(ContractDataVO::getGmtCreate, Comparator.reverseOrder()))
                .collect(Collectors.toList());
        // 避免出现因为没有开始时间导致数据被过滤的情况
        if (!CollectionUtils.isEmpty(dataVOList)) {
            return dataVOList;
        }
        return contractDataVOS.parallelStream()
                .sorted(Comparator.comparing(ContractDataVO::getGmtCreate).reversed())
                .collect(Collectors.toList());
    }

    /**
     * 多线程将花名册电子合同转为合同； List<EmpContractDO> =》 List<ContractDataVO>
     *
     * @param empContractDOS 花名册电子合同
     * @return 合同
     */
    private List<ContractDataVO> empContractToContractList(List<EmpContractDO> empContractDOS) {
        if (CollectionUtils.isEmpty(empContractDOS)) {
            return new ArrayList<>();
        }
        return empContractDOS.parallelStream().map(empContractDO -> {
            ContractDataVO contractDataVO = new ContractDataVO();
            contractDataVO.setFileType(empContractDO.getType());
            contractDataVO.setName(empContractDO.getName());
            contractDataVO.setGmtCreate(empContractDO.getGmtCreate());
            contractDataVO.setStartDate(empContractDO.getStartTime());
            contractDataVO.setEndDate(empContractDO.getEndTime());
            contractDataVO.setDateline(getEmpContractTermMonth(empContractDO));
            return contractDataVO;
        }).collect(Collectors.toList());
    }

    /**
     * 多线程将花名册纸质合同转为合同； List<EmpContractDO> =》 List<ContractDataVO>
     *
     * @param empPaperContractDOS 花名册纸质合同
     * @return 合同
     */
    private List<ContractDataVO> empPaperContractToContractList(List<EmpPaperContractDO> empPaperContractDOS) {
        if (CollectionUtils.isEmpty(empPaperContractDOS)) {
            return new ArrayList<>();
        }
        return empPaperContractDOS.parallelStream().map(empPaperContractDO -> {
            ContractDataVO contractDataVO = new ContractDataVO();
            contractDataVO.setFileType(empPaperContractDO.getType());
            contractDataVO.setName(empPaperContractDO.getName());
            contractDataVO.setGmtCreate(empPaperContractDO.getGmtCreate());
            contractDataVO.setStartDate(empPaperContractDO.getStartTime());
            contractDataVO.setEndDate(empPaperContractDO.getEndTime());
            contractDataVO.setDateline(getEmpPaperContractTermMonth(empPaperContractDO));
            return contractDataVO;
        }).collect(Collectors.toList());
    }

    /**
     * 获取花名册纸质合同期限，单位：月
     */
    private int getEmpPaperContractTermMonth(EmpPaperContractDO empPaperContractDO) {
        if (empPaperContractDO == null) {
            return 0;
        }
        // 纸质合同期限：年
        int LIMIT_TYPE_YEAR = 1;
        // 纸质合同期限：月
        int LIMIT_TYPE_MONTH = 2;
        // 合同时间
        int timeLimit = empPaperContractDO.getTimeLimit() == null ? 0 : empPaperContractDO.getTimeLimit();
        // 时间单位 1：年 2： 月
        Integer timeLimitType = empPaperContractDO.getTimeLimitType();
        if (timeLimitType == null) {
            return 0;
        }
        int monthCount = 0;
        if (Objects.equals(timeLimitType, LIMIT_TYPE_YEAR)) {
            monthCount = 12;
        } else if (Objects.equals(timeLimitType, LIMIT_TYPE_MONTH)) {
            monthCount = 1;
        }
        return timeLimit * monthCount;
    }

    /**
     * 获取花名册电子合同期限，单位：月
     */
    private int getEmpContractTermMonth(EmpContractDO empContractDO) {
        if (empContractDO == null) {
            return 0;
        }
        // 年
        int termYear = empContractDO.getTermYear() == null ? 0 : empContractDO.getTermYear();
        // 月
        int termMonth = empContractDO.getTermMonth() == null ? 0 : empContractDO.getTermMonth();
        // 日
        int termDay = empContractDO.getTermDay() == null ? 0 : empContractDO.getTermDay();
        // 统一处理为月份
        return termYear * 12 + termMonth + termDay / 30;
    }

    /**
     * 查询所有在职员工，无其他任何字段填充
     *
     * @param empInfoQuery query对象
     * @param tokenUser    当前登录用户
     * @return list
     */
    private List<EmpInfoListVO> listOnJobEmpListWithoutExtend(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);

        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        return empInfoList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class))
                .collect(Collectors.toList());
    }

    /**
     * 拼接数据库 FIND_IN_SET() 函数
     *
     * @param example   example
     * @param columns   查询数据
     * @param sqlColumn sql字段
     */
    private void findInSet(Example example, List<String> columns, String sqlColumn) {
        if (example == null || CollectionUtils.isEmpty(columns) || StrKit.isEmpty(sqlColumn)) {
            return;
        }
        for (String column : columns) {
            example.and().andCondition("FIND_IN_SET('" + column + "' , " + sqlColumn + ")");
        }
    }

    @Override
    public List<EmpInfoListVO> listLeaveRelation(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            // 查询tag
            findInSet(example, tagList, SQL_TAG);
        }

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .andEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue());

        return listVoRelationByExample(empInfoQuery.getCompanyId(), example, tokenUser.getSiteId());
    }

    private List<EmpInfoListVO> listVoRelationByExample(String companyId, Example example, String siteId) {
        long l1 = System.currentTimeMillis();
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);
        long l2 = System.currentTimeMillis();
        log.info("======查询{}条员工信息，耗时：{}ms", empInfoList.size(), (l2 - l1));
        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        List<EmpInfoListVO> empInfoVoList = empInfoList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class))
                .collect(Collectors.toList());
        long l3 = System.currentTimeMillis();
        // 增加部门和岗位信息
        addDepAndPositionToEmpList(empInfoVoList, companyId, siteId);
        long l4 = System.currentTimeMillis();
        log.info("======{}条员工部门和岗位信息赋值：{}ms", empInfoList.size(), (l4 - l3));
        return empInfoVoList;
    }

    @Override
    public Page<EmpInfoListVO> pageTransfer(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = buildExample(empInfoQuery, tokenUser);
        // 获取已调岗员工
        List<String> empIdList = empChangesService.listTransferEmp(empInfoQuery.getCompanyId(), tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(empIdList)) {
            empIdList = new ArrayList<>();
        }
        example.and().andIn("id", empIdList);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());

        return pageVoByExample(example, empInfoQuery.getCompanyId(), empInfoQuery.getPageNo(), empInfoQuery.getPageSize(), tokenUser.getSiteId());
    }

    private Page<EmpInfoListVO> pageVoByExample(Example example, String companyId, Integer pageNo, Integer pageSize, String siteId) {
        Page<EmpInfoDO> page = empInfoDAO.selectPageByExample(example, pageNo, pageSize);

        if (CollectionUtils.isEmpty(page.getEntities())) {
            return new Page<>(pageSize, pageNo);
        }
        Page<EmpInfoListVO> pageVo = page.to(EmpInfoListVO.class);
        List<EmpInfoListVO> empInfoList = pageVo.getEntities();
        // 增加部门和岗位信息
        addDepAndPositionToEmpList(empInfoList, companyId, siteId);
        pageVo.setEntities(empInfoList);

        return pageVo;
    }

    @Override
    public List<EmpInfoContractVO> getEmpInfoListForContract(String[] empIdList, Long templateId, String siteId) {
        if (empIdList == null || empIdList.length == 0) {
            throw new ParamException("没有需要查询的数据");
        }
        // 查询员工
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("id", Arrays.asList(empIdList))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());

        example.orderBy("gmtCreate").desc().orderBy("id").desc();

        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);

        if (CollectionUtils.isEmpty(empInfoList)) {
            return null;
        }

        // 所属的所有公司id
        List<String> companyIdList = empInfoList.parallelStream()
                .map(EmpInfoDO::getCompanyId).distinct().collect(Collectors.toList());

        // 公司map<companyId,CompanyDO>
        Map<String, CompanyDO> companyMap = new HashMap<>();
        // 员工部门map<empId,员工所属部门集合>
        Map<String, List<EmpReduceInfoVO>> empDepMap = new HashMap<>();
        // 员工部门map<empId,员工所属岗位集合>
        Map<String, List<EmpReduceInfoVO>> empPositionMap = new HashMap<>();
        companyIdList.parallelStream().forEach(
                companyId -> {
                    // 公司信息
                    CompanyDO company = companyService.selectDOById(companyId, siteId);
                    if (Objects.nonNull(company)) {
                        // 公司
                        companyMap.put(company.getId(), company);
                        //  公司员工与部门的关系
                        Map<String, List<EmpReduceInfoVO>> depMap = getEmpDepMap(companyId, siteId);
                        if (depMap.size() > 0) {
                            empDepMap.putAll(depMap);
                        }

                        // 公司员工与岗位的关系
                        Map<String, List<EmpReduceInfoVO>> positionMap = getEmpPositionMap(companyId, siteId);
                        if (positionMap.size() > 0) {
                            empPositionMap.putAll(positionMap);
                        }
                    }
                }
        );

        // 构建员工合同信息List
        return buildEmpContractInfoList(empInfoList, companyMap, empDepMap, empPositionMap, templateId, siteId);
    }

    /**
     * 构建员工合同信息列表
     *
     * @param empInfoList    员工列表
     * @param companyMap     公司map<companyId,公司信息>
     * @param empDepMap      员工部门map<empId,员工所属部门>
     * @param empPositionMap 员工岗位map<empId,员工所属岗位>
     * @param templateId     模板id
     * @param siteId         站点id
     * @return 员工合同信息列表
     */
    private List<EmpInfoContractVO> buildEmpContractInfoList(List<EmpInfoDO> empInfoList, Map<String, CompanyDO> companyMap, Map<String, List<EmpReduceInfoVO>> empDepMap, Map<String, List<EmpReduceInfoVO>> empPositionMap, Long templateId, String siteId) {
        List<EmpInfoContractVO> empInfoContractList = new ArrayList<>();

        // 模板
        TemplateDO templateDO = contractProviderService.getTemplateById(templateId, siteId);
        // 合同类型
        CategoryVO categoryVO = null;
        if (Objects.nonNull(templateDO)) {
            // 合同类型
            categoryVO = contractProviderService.selectCategoryById(templateDO.getCategoryId(), siteId);
        }

        for (EmpInfoDO empInfoDO : empInfoList) {
            EmpInfoContractVO empInfoContractVO = empInfoDO.to(EmpInfoContractVO.class);
            empInfoContractVO.setEmpId(empInfoDO.getId());
            empInfoContractVO.setTypeName("身份证");
            empInfoContractVO.setGenderName(empInfoDO.getGender() == null ? "" : (empInfoDO.getGender() == 1 ? "男" : "女"));

            if (empInfoDO.getProbationDays() != null) {
                empInfoContractVO.setProbationName(empInfoDO.getProbationDays() + " 天");
            }
            empInfoContractVO.setProbationStartTime(empInfoDO.getJoinDate());
            empInfoContractVO.setTurnStraightDate(empInfoDO.getTurnStraightDate());

            // 公司
            if (!companyMap.containsKey(empInfoDO.getCompanyId())) {
                continue;
            }
            CompanyDO companyDO = companyMap.get(empInfoDO.getCompanyId());

            empInfoContractVO.setCompanyName(companyDO.getName());
            empInfoContractVO.setLegalPerson(companyDO.getLegalPerson());
            empInfoContractVO.setContactPerson(companyDO.getLegalPerson());
            empInfoContractVO.setAddress(companyDO.getAddress());

            // 教育信息
            EmpEducationQuery empEducationQuery = new EmpEducationQuery();
            empEducationQuery.setEmpId(empInfoDO.getId());
            empEducationQuery.setIsFirstEdu(true);
            List<EmpEducationDO> educationList = empEducationService.selectDO(empEducationQuery, siteId);
            if (!CollectionUtils.isEmpty(educationList)) {
                EmpEducationDO empEducationDO = educationList.get(0);
                empInfoContractVO.setGraCollege(empEducationDO.getGraCollege());
                empInfoContractVO.setMajor(empEducationDO.getMajor());
                empInfoContractVO.setEduStartTime(empEducationDO.getStartTime());
                empInfoContractVO.setEduEndTime(empEducationDO.getEndTime());

                empInfoContractVO.setEducation(empEducationDO.getEducation());
                empInfoContractVO.setTeaMethods(empEducationDO.getTeaMethods());
                empInfoContractVO.setGraCerNumber(empEducationDO.getGraCerNumber());
                empInfoContractVO.setDegreeType(empEducationDO.getDegreeType());
                empInfoContractVO.setDegreeName(empEducationDO.getDegreeName());
                empInfoContractVO.setDegreeNumber(empEducationDO.getDegreeNumber());
                empInfoContractVO.setEducationRemark(empEducationDO.getEducationRemark());
            }

            // 部门
            String depNames = getDepNameByEmpId(empInfoDO.getId(), empDepMap);
            empInfoContractVO.setDepName(depNames);

            // 岗位
            String positionNames = getPositionNameByEmpId(empInfoDO.getId(), empPositionMap);
            empInfoContractVO.setPositionName(positionNames);

            // 家庭成员
            List<EmpFamilyDO> empFamilyDOList = empFamilyService.listByEmpId(empInfoDO.getId(), siteId);
            if (!CollectionUtils.isEmpty(empFamilyDOList)) {
                EmpFamilyDO empFamilyDO = empFamilyDOList.get(0);
                empInfoContractVO.setFamilyContact(empFamilyDO.getName());
                empInfoContractVO.setFamilyPhone(empFamilyDO.getPhone());
                empInfoContractVO.setFamilyLocation(empFamilyDO.getWorkUnit());
                empInfoContractVO.setFamilyRelation(empFamilyDO.getRelation());
            }

            // 紧急联系人
            List<EmpContactsDO> empContactsList = empContactsService.listByEmpId(empInfoDO.getId(), siteId);
            if (!CollectionUtils.isEmpty(empContactsList)) {
                EmpContactsDO empContactsDO = empContactsList.get(0);
                empInfoContractVO.setEmerContact(empContactsDO.getName());
                empInfoContractVO.setEmerPhone(empContactsDO.getPhone());
                empInfoContractVO.setEmerLocation(empContactsDO.getAddress());
                empInfoContractVO.setEmerRelation(empContactsDO.getRelation());
            }

            // 合同相关
            if (Objects.nonNull(categoryVO)) {

                String fileType = categoryVO.getFileType();
                // 员工合同信息
                List<EmpContractDO> empContractList = empContractService.listByType(empInfoDO.getId(), fileType, siteId);
                if (!CollectionUtils.isEmpty(empContractList)) {
                    EmpContractDO empContractDO = empContractList.get(0);
                    if (empContractDO.getStartTime() != null) {
                        empInfoContractVO.setContractStartTime(DateKit.getDateStr(empContractDO.getStartTime()));
                    } else {
                        empInfoContractVO.setContractStartTime("");
                    }
                    if (empContractDO.getEndTime() != null) {
                        empInfoContractVO.setContractEndTime(DateKit.getDateStr(empContractDO.getEndTime()));
                    } else {
                        empInfoContractVO.setContractEndTime("");
                    }
                    if (empContractDO.getTermYear() != null && empContractDO.getTermYear() != 0) {
                        empInfoContractVO.setContractExpire(empContractDO.getTermYear() + " 年");
                    } else if (empContractDO.getTermMonth() != null) {
                        empInfoContractVO.setContractExpire(empContractDO.getTermMonth() + " 月");
                    } else {
                        empInfoContractVO.setContractExpire("");
                    }
                }
                // 员工的合同类型 使用合同模板的合同类型
                empInfoContractVO.setContractType(fileType);
            }

            empInfoContractVO.setWorkAddress(empInfoDO.getWorkCity());
            empInfoContractList.add(empInfoContractVO);
        }

        //合同属性集合
        for (EmpInfoContractVO empVO : empInfoContractList) {
            List<Map<String, Object>> variableMapList = contractProviderService.getVariableMapList(templateId, siteId);
            // 自定义变量信息
            List<CompanyAdditionalFieldsDO> companyAdditionalFieldsDOList
                    = companyAdditionalFieldsService.selectOpenDoByCompanyId(empVO.getCompanyId(), siteId);
            // 自定义变量名称-自定义变量Id
            Map<String, Long> fieldNameIdMap = companyAdditionalFieldsDOList.parallelStream().filter(companyAdditionalFieldsDO -> {
                // 过滤入职模板、待入职模板中的自定义变量 只保留花名册的
                if (companyAdditionalFieldsDO.getTemplateId() != null) {
                    return false;
                }
                String fieldName = companyAdditionalFieldsDO.getFieldName();
                if ("basic".equals(companyAdditionalFieldsDO.getModuleCode())) {
                    fieldName += "(基本信息)";
                } else if ("contact".equals(companyAdditionalFieldsDO.getModuleCode())) {
                    fieldName += "(联系信息)";
                } else {
                    return false;
                }
                companyAdditionalFieldsDO.setFieldName(fieldName);
                return true;
            }).collect(Collectors.toMap(CompanyAdditionalFieldsDO::getFieldName, BaseDO::getId, (v1, v2) -> v1));
            // 自定义字段输入值
            List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList
                    = empAdditionalFieldsService.selectByCompanyId(empVO.getId(), empVO.getCompanyId(), null, siteId);
            // 如果字段类型是地区选择 则需要替换内容
            for (EmpAdditionalFieldsDO empAdditionalFieldsDO : empAdditionalFieldsDOList) {
                if (StrKit.isEmpty(empAdditionalFieldsDO.getContent())) {
                    continue;
                }
                CompanyAdditionalFieldsDO companyAdditionalFieldsDO = companyAdditionalFieldsService
                        .selectByIdNoSite(empAdditionalFieldsDO.getFieldId());
                if (companyAdditionalFieldsDO == null
                        || companyAdditionalFieldsDO.getFieldType() == null
                        || companyAdditionalFieldsDO.getFieldType() != 6) {
                    continue;
                }
                List<String> areaIdList = ArrayKit.split(empAdditionalFieldsDO.getContent(), ",");
                StringBuilder content = new StringBuilder();
                for (int i = 0; i < areaIdList.size(); i++) {
                    content.append(adminProviderService.selectAreaById(areaIdList.get(i)));
                    if (i + 1 < areaIdList.size()) {
                        content.append("-");
                    }
                }
                empAdditionalFieldsDO.setContent(content.toString());
            }
            Map<Long, String> fieldIdContentMap = empAdditionalFieldsDOList.parallelStream().filter(empAdditionalFieldsDO -> {
                if (empAdditionalFieldsDO.getFieldId() == null) {
                    return false;
                }
                if (empAdditionalFieldsDO.getContent() == null) {
                    empAdditionalFieldsDO.setContent("");
                }
                return true;
            }).collect(Collectors
                    .toMap(EmpAdditionalFieldsDO::getFieldId, EmpAdditionalFieldsDO::getContent, (v1, v2) -> v1));
            // 变量名-变量值
            for (Map<String, Object> stringObjectMap : variableMapList) {
                for (String variableName : stringObjectMap.keySet()) {
                    String content = getContent(empVO, variableName, siteId);
                    // 员工信息
                    HashMap map = (HashMap) stringObjectMap.get(variableName);
                    if (StringUtils.isNotBlank(content)) {
                        map.put("content", content);
                    } else {
                        Long fieldId = fieldNameIdMap.get(variableName);
                        if (fieldId != null) {
                            map.put("content", fieldIdContentMap.get(fieldId));
                        }
                    }
                }
            }
            empVO.setConVariableMap(variableMapList);
        }
        return empInfoContractList;
    }

    @Override
    public List<EmpInfoContractVO> getEmpContractInfoList(ContractEmpInfoDTO contractEmpInfoDTO, String siteId) {
        // 所有员工
        List<EmpInfoDO> empInfoList = listByCompanyId(contractEmpInfoDTO.getCompanyId(), siteId);

        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        // 筛选
        empInfoList = empInfoList.stream()
                .filter(empInfo -> contractEmpInfoDTO.getEmpIdList().contains(empInfo.getId()))
                .collect(Collectors.toList());

        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }

        String companyId = contractEmpInfoDTO.getCompanyId();


        // 员工部门map<empId,员工所属部门集合>
        Map<String, List<EmpReduceInfoVO>> empDepMap = getEmpDepMap(companyId, siteId);
        // 员工部门map<empId,员工所属岗位集合>
        Map<String, List<EmpReduceInfoVO>> empPositionMap = getEmpPositionMap(companyId, siteId);
        // 公司
        CompanyDO company = companyService.selectDOById(companyId, siteId);

        // 公司map<companyId,CompanyDO>
        Map<String, CompanyDO> companyMap = new HashMap<>();
        companyMap.put(company.getId(), company);

        // 构建员工合同信息List
        return buildEmpContractInfoList(empInfoList, companyMap, empDepMap, empPositionMap, contractEmpInfoDTO.getTemplateId(), siteId);
    }

    private String getContent(EmpInfoContractVO empVO, String name, String siteId) {
        BigDecimal trainingSalarySum = BigDecimal.ZERO;
        BigDecimal officialSalarySum = BigDecimal.ZERO;
        String empId = empVO.getId();
        String companyId = empVO.getCompanyId();
        if ("税前工资".equals(name) || "试用期税前工资".equals(name)) {
            // 查询员工定薪
            List<EmpFixedSalaryDO> empFixedSalaryDOList = salaryProviderService
                    .selectFixedSalaryByEmpIds(Collections.singletonList(empId));
            if (!CollectionUtils.isEmpty(empFixedSalaryDOList)) {
                trainingSalarySum = empFixedSalaryDOList.get(0).getTrainingSalarySum();
                officialSalarySum = empFixedSalaryDOList.get(0).getOfficialSalarySum();
            }
        }

        switch (name) {
            case "企业联系人":
                return empVO.getContactPerson();
            case "企业法定代表人":
                return empVO.getLegalPerson();
            case "企业公司地址":
                return empVO.getAddress();
            case "员工姓名":
            case "姓名":
                return empVO.getName();
            case "签约主体":
                return empVO.getContractSubject();
            case "身份证号":
            case "证件号码":
                return empVO.getIdCard();
            case "出生日期":
                String birthday = empVO.getBirthday();
                if (StrKit.isNotEmpty(birthday) && birthday.length() > 10) {
                    birthday = birthday.substring(0, 10);
                }
                return birthday;
            case "年龄":
                if (empVO.getEmpAge() != null) {
                    return empVO.getEmpAge() + "岁";
                }
                return null;
            case "户口类型":
                if (empVO.getRegType() != null) {
                    switch (empVO.getRegType()) {
                        case 1:
                            return "城镇户口";
                        case 2:
                            return "农村户口";
                        case 3:
                            return "居民户口";
                    }
                }
                return null;
            case "政治面貌":
                if (empVO.getPoliticalStatus() != null) {
                    switch (empVO.getPoliticalStatus()) {
                        case 1:
                            return "中共党员";
                        case 2:
                            return "共青团员";
                        case 3:
                            return "普通居民/群众";
                        case 4:
                            return "其它";
                    }
                }
                return null;
            case "证件类型":
                return empVO.getTypeName();
            case "性别":
                return empVO.getGenderName();
            case "联系电话":
            case "手机号":
                return empVO.getPhone();
            case "生育状况":
                if (empVO.getBirthStatus() != null) {
                    switch (empVO.getBirthStatus()) {
                        case 1:
                            return "已生育";
                        case 2:
                            return "未生育";
                    }
                }
                return null;
            case "婚姻状况":
                if (empVO.getMaritalStatus() != null) {
                    switch (empVO.getMaritalStatus()) {
                        case 1:
                            return "已婚";
                        case 2:
                            return "未婚";
                    }
                }
                return null;
            case "个人邮箱":
            case "邮箱":
                return empVO.getEmail();
            case "民族":
                return empVO.getNation();
            case "血型":
                if (empVO.getBloodGroup() != null) {
                    switch (empVO.getBloodGroup()) {
                        case 1:
                            return "A";
                        case 2:
                            return "B";
                        case 3:
                            return "AB";
                        case 4:
                            return "O";
                        case 5:
                            return "其它";
                    }
                }
                return null;
            case "现居住地":
                return empVO.getCurrentLocation();
            case "户籍地址":
                return empVO.getNativeLocation();
            case "紧急联系人姓名":
            case "联系人姓名(紧急联系人)":
                return empVO.getEmerContact();
            case "紧急联系人电话":
            case "联系电话(紧急联系人)":
                return empVO.getEmerPhone();
            case "紧急联系人地址":
            case "联系人地址(紧急联系人)":
                return empVO.getEmerLocation();
            case "紧急联系人关系":
            case "与我的关系(紧急联系人)":
                return empVO.getEmerRelation();
            case "成员姓名(家庭成员)":
                return empVO.getFamilyContact();
            case "与我的关系(家庭成员)":
                return empVO.getFamilyRelation();
            case "联系电话(家庭成员)":
                return empVO.getFamilyPhone();
            case "工作单位(家庭成员)":
                return empVO.getFamilyLocation();
            case "工资卡开户行":
                return empVO.getBankCardBranch();
            case "工资卡卡号":
                return empVO.getBankCard();
            case "学历":
                if (empVO.getEducation() != null) {
                    switch (empVO.getEducation()) {
                        case 1:
                            return "小学";
                        case 2:
                            return "初中";
                        case 3:
                            return "中专";
                        case 4:
                            return "高中";
                        case 5:
                            return "大专";
                        case 6:
                            return "本科";
                        case 7:
                            return "硕士";
                        case 8:
                            return "博士";
                        case 9:
                            return "其他";
                    }
                }
                return null;
            case "毕业院校":
                return empVO.getGraCollege();
            case "毕业专业":
                return empVO.getMajor();
            case "教育开始时间":
                return DateKit.getDateStr(empVO.getEduStartTime());
            case "教育结束时间":
                return DateKit.getDateStr(empVO.getEduEndTime());
            case "学习形式":
                if (empVO.getTeaMethods() != null) {
                    switch (empVO.getTeaMethods()) {
                        case "1":
                            return "全日制";
                        case "2":
                            return "成人教育";
                        case "3":
                            return "远程教育";
                        case "4":
                            return "自学考试";
                        case "5":
                            return "其他非全日制";
                    }
                }
                return null;
            case "毕业证书编号":
                return empVO.getGraCerNumber();
            case "学位类型":
                if (empVO.getDegreeType() != null) {
                    switch (empVO.getDegreeType()) {
                        case 1:
                            return "学士";
                        case 2:
                            return "硕士";
                        case 3:
                            return "博士";
                        case 4:
                            return "未获得学位";
                    }
                }
                return null;
            case "学位名称":
                return empVO.getDegreeName();
            case "学位证书编号":
                return empVO.getDegreeNumber();
            case "教育备注":
                return empVO.getEducationRemark();
            case "部门":
                return empVO.getDepName();
            case "部门负责人":
                return empVO.getDepLeader();
            case "岗位":
                return empVO.getPositionName();
            case "用工企业名称":
                return empVO.getCompanyName();
            case "工作地点":
                return empVO.getWorkAddress();
            case "试用期":
                return empVO.getProbationName();
            case "合同开始时间":
                return empVO.getContractStartTime();
            case "合同结束时间":
                return empVO.getContractEndTime();
            case "合同期限":
                return empVO.getContractExpire();
            case "合同编号":
                return empVO.getContractNumber();
            case "试用期开始日期":
                return DateKit.getDateStr(empVO.getProbationStartTime());
            case "试用期结束日期":
                return DateKit.getDateStr(empVO.getProbationEndTime());
            case "税前工资":
                return trainingSalarySum + "元";
            case "试用期税前工资":
                return officialSalarySum + "元";
            case "入职日期":
                return DateKit.getDateStr(empVO.getJoinDate());
            case "转正日期":
                return DateKit.getDateStr(empVO.getTurnStraightDate());
            case "离职日期":
                return DateKit.getDateStr(empVO.getLeaveDate());
            case "离职原因":
                return empVO.getLeaveReason();
            case "签署确认时间":
//              return " 2020年 05月 22日 ";
//                return "<signDateReplace>";
                return SIGN_CONFIRM_DATE_REPLACE;
            default:
                return null;
        }
    }

    @Override
    public EmpInfoListVO selectEmpAndDepPositionById(String empInfoId, String siteId) {
        EmpInfoDO empInfoDO = selectDOById(empInfoId, siteId);
        if (Objects.isNull(empInfoDO)) {
            return null;
        }
        EmpInfoListVO empInfoListVO = empInfoDO.to(EmpInfoListVO.class);
        // 将部门和岗位添加到员工身上,关联关系的
        addDepAndPositionToEmpByRelation(empInfoListVO, siteId);
        return empInfoListVO;
    }


    @Override
    public void checkByPhone(String phone, String siteId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("phone", phone)
                .andEqualTo("siteId", siteId)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("valid", true);

        EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
        if (Objects.nonNull(empInfoDO)) {
            // 公司还在就报错
            String companyOtherId = empInfoDO.getCompanyId();
            CompanyDO companyDO = companyService.selectDOById(companyOtherId, siteId);
            if (Objects.nonNull(companyDO)) {
                // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
                if (empInfoDO.getStatus().equals(WAIT_ENTRY.getValue())) {
                    throw new ParamException(phone + "手机号已在 " + companyDO.getName() + " 添加待入职信息,请先去完成操作");
                } else {
                    throw new ParamException(phone + "手机号已入职 " + companyDO.getName() + " 请前往花名册更换用工单位或删除员工");
                }
            } else {
                log.info("删除公司后没删除员工");
                // 否则删除之前的记录 让他创建
                TokenUser deleteTokenUser = new TokenUser();
                deleteTokenUser.setUserId(tokenUser.getUserId());
                deleteTokenUser.setSiteId(siteId);
                deleteByIds(deleteTokenUser, empInfoDO.getId());
            }
        }
    }

    @Override
    public void checkOnJobIdCard(String companyId, String idCard, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("idCard", idCard)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andNotEqualTo("companyId", companyId)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);

        EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
        if (Objects.nonNull(empInfoDO)) {
            String companyOtherId = empInfoDO.getCompanyId();
            CompanyDO companyDO = companyService.selectDOById(companyOtherId, siteId);
            if (Objects.nonNull(companyDO)) {
                // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
                if (empInfoDO.getStatus().equals(WAIT_ENTRY.getValue())) {
                    throw new ParamException(idCard + "身份证号已在 " + companyDO.getName() + " 添加待入职信息,请先去完成操作");
                } else {
                    throw new ParamException(idCard + "身份证号已入职 " + companyDO.getName());
                }
            }
        }
    }

    @Override
    public List<EmpReduceInfoVO> listNoDepEmp(String companyId, EmpReduceQuery empReduceQuery, TokenUser tokenUser) {
        empReduceQuery.setInDep(false);
        return listEmpReduceByInfo(companyId, empReduceQuery, tokenUser);
    }

    /**
     * 根据条件获取员工信息
     *
     * @param companyId      公司id
     * @param empReduceQuery 查询条件
     * @param tokenUser      当前用户
     * @return 员工信息
     */
    private List<EmpReduceInfoVO> listEmpReduceByInfo(String companyId, EmpReduceQuery empReduceQuery, TokenUser tokenUser) {
        // 所有员工
        List<EmpReduceInfoVO> empReduceInfoList = listEmpReduceAndDepInfo(companyId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(empReduceInfoList)) {
            return new ArrayList<>();
        }
        // 是否是分公司
        boolean isChild = false;

        List<String> empInDep = empReduceInfoList.parallelStream()
                // 有部门的员工
                .filter(empInfo -> empInfo.getDepIsValid() != null)
                .map(EmpReduceInfoVO::getId).distinct()
                .collect(Collectors.toList());

        // 员工名称或手机号
        String empNameOrPhone = empReduceQuery.getEmpNameOrPhone();
        // 是否只是user的用户,null:全部,true:是用户,false:不是用户
        Boolean onlyUser = empReduceQuery.getOnlyUser();
        // 在职还是离职,null:全部,true:在职,false:离职
        Boolean isOnlineOrLeave = empReduceQuery.getIsOnlineOrLeave();
        // 是否在部门中,null:全部,true:在部门中,false:非部门员工
        Boolean inDep = empReduceQuery.getInDep();

        boolean finalIsChild = isChild;

        // 员工与部门的关系
        Map<String, List<EmpReduceInfoVO>> empDepMap = new HashMap<>();
        if (inDep == null || inDep) {
            // 全部和有部门的时候
            empDepMap = getEmpDepMap(companyId, tokenUser.getSiteId());
        }

        // 员工与岗位的关系
        Map<String, List<EmpReduceInfoVO>> empPositionMap = getEmpPositionMap(companyId, tokenUser.getSiteId());

        Map<String, List<EmpReduceInfoVO>> finalEmpDepMap = empDepMap;
        List<EmpReduceInfoVO> empInfoList = empReduceInfoList.stream()
                .filter(empInfo -> {
                    // 姓名或手机号
                    if (StringUtils.isNotEmpty(empNameOrPhone)) {
                        if (empNameOrPhone.contains(",")) {
                            // 根据多手机号匹配,158xxxxxxxx,158xxxxxxxx
                            if (!empNameOrPhone.contains(empInfo.getPhone())) {
                                return false;
                            }
                        } else {
                            // // 姓名/手机号模糊查询
                            if (!empInfo.getName().contains(empNameOrPhone)
                                    && !empInfo.getPhone().contains(empNameOrPhone)) {
                                return false;
                            }
                        }
                    }
                    // 是否只是user的用户,null:全部,true:是用户,false:不是用户
                    if (onlyUser != null) {
                        if (onlyUser) {
                            // 用户
                            if (StringUtils.isEmpty(empInfo.getUserId())) {
                                return false;
                            }
                        } else {
                            // 非用户
                            if (StringUtils.isNotEmpty(empInfo.getUserId())) {
                                return false;
                            }
                        }
                    }
                    // 员工状态
                    if (isOnlineOrLeave != null) {
                        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
                        if (isOnlineOrLeave) {
                            if (empInfo.getStatus() != 2 && empInfo.getStatus() != 3) {
                                return false;
                            }
                        } else {
                            if (empInfo.getStatus() != 4) {
                                return false;
                            }
                        }
                    }
                    //  是否是部门员工
                    if (inDep != null) {
                        if (inDep) {
                            // 有部门的员工
                            return empInDep.contains(empInfo.getId());
                        } else {
                            // 没有部门的员工
                            return !empInDep.contains(empInfo.getId());
                        }
                    }
                    return true;
                })
                .peek(empInfo -> {
                    // 增加部门信息
                    if (inDep == null || inDep) {
                        // 部门
                        String depNames = getDepNameByEmpId(empInfo.getId(), finalEmpDepMap);
                        empInfo.setDepName(depNames);
                    }
                    // 岗位
                    String positionNames = getPositionNameByEmpId(empInfo.getId(), empPositionMap);
                    empInfo.setPositionName(positionNames);
                })
                .collect(Collectors.toList());

        return empInfoList;
    }

    @Override
    public List<EmpReduceInfoVO> listOnJobByCompanyId(String companyId, EmpReduceQuery empReduceQuery, TokenUser tokenUser) {
        empReduceQuery.setInDep(null);
        return listEmpReduceByInfo(companyId, empReduceQuery, tokenUser);
    }

    @Override
    public Map<String, String> listEmpJoinCity(String companyId, String siteId) {
        // 在职员工所有的工作城市
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andIsNotNull("joinCityCode")
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        // 查地区只查那几个字段就
        example.selectProperties("joinCityCode", "joinCityName");

        example.orderBy("joinCityCode").orderBy("id");
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoList)) {
            return null;
        }
        return empInfoList.stream().collect(
                Collectors.toMap(
                        EmpInfoDO::getJoinCityCode,
                        empInfoDO -> StringUtils.isEmpty(empInfoDO.getJoinCityName()) ? "" : empInfoDO.getJoinCityName()
                )
        );
    }

    @Override
    public List<EmpInfoDO> listOnJobByCompanyId(String companyId, String siteId) {
        List<EmpInfoDO> empInfoList = listByCompanyId(companyId, siteId);
        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        return empInfoList.stream()
                .filter(empInfo -> 2 == empInfo.getStatus() || 3 == empInfo.getStatus())
                .collect(Collectors.toList());
    }

    @Override
    public List<EmpInfoDO> listByCompanyId(String companyId, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        example.orderBy("gmtCreate").desc().orderBy("id").desc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public boolean sendChangePhoneMessage(String oldPhone, String newPhone, TokenUser tokenUser) {

        String thirdId = siteConfigProviderService.selectValueByCode(ConfigCodeConstants.CODE_CHANGE_PHONE_THIRD_ID,
                tokenUser.getSiteId());
        // 校验员工是否能修改手机号
        getAndCheckEmpChangePhone(oldPhone, newPhone, tokenUser);

        // 发送验证码
        //发送短信验证码
        ShortMessageDTO shortMessageDTO = new ShortMessageDTO();
        shortMessageDTO.setPhone(newPhone);
        shortMessageDTO.setThirdId(thirdId);
        shortMessageDTO.setScene("hr_emp_change_phone_" + oldPhone);

        return messageProviderService.sendShortMessage(shortMessageDTO, tokenUser);
    }

    /**
     * 获取手机号对应的要修改的员工信息,并校验能否修改
     *
     * @param oldPhone  要修改的手机号对应的员工
     * @param newPhone  要修改的手机号对应的员工
     * @param tokenUser 当前用户
     */
    private List<EmpInfoDO> getAndCheckEmpChangePhone(String oldPhone, String newPhone, TokenUser tokenUser) {
        List<EmpInfoDO> phoneEmpList = listByPhone(oldPhone, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(phoneEmpList)) {
            throw new ParamException("手机号对应的员工不存在");
        }
        // 校验是否本人
        for (EmpInfoDO empInfo : phoneEmpList) {
            if (!empInfo.getUserId().equals(tokenUser.getUserId())) {
                throw new ParamException("当前用户不是员工本人,不能修改");
            }
            EmpInfoVO newPhoneEmp = selectByPhone(empInfo.getCompanyId(), newPhone, tokenUser.getSiteId());
            if (Objects.nonNull(newPhoneEmp)) {
                CompanyDO companyDO = companyService.selectDOById(empInfo.getCompanyId(), tokenUser.getSiteId());
                if (Objects.nonNull(companyDO)) {
                    throw new ParamException("新手机号'" + newPhone + "'在公司'" + companyDO.getName() + "'中已有人员在使用,无法更改");
                }
            }
        }
        return phoneEmpList;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void updateEmpPhone(String oldPhone, String newPhone, String captcha, TokenUser tokenUser) {
        // 获取手机号对应的要修改的员工信息,并校验能否修改
        List<EmpInfoDO> phoneEmpList = getAndCheckEmpChangePhone(oldPhone, newPhone, tokenUser);
        // 校验验证码

        String scene = "hr_emp_change_phone_" + oldPhone;
        boolean checkCode = messageProviderService.verifyCaptcha(scene, newPhone, captcha);
        if (!checkCode) {
            throw new ParamException("验证码不正确");
        }

        for (EmpInfoDO empInfo : phoneEmpList) {
            EmpInfoDO empInfoUp = new EmpInfoDO();
            empInfoUp.setId(empInfo.getId());
            empInfoUp.setPhone(newPhone);
            // 更新员工手机号
            updateByIdSelective(empInfoUp, tokenUser.getSiteId(), tokenUser.getUserId());

            // 更新员工合同信息
            contractProviderService.updateUserPhone(oldPhone, empInfo.getUserId(), newPhone, tokenUser);

            // 修改用户的手机号
            userProviderService.updateUserPhone(empInfo.getUserId(), oldPhone, newPhone, tokenUser);
        }
    }

    /**
     * 查询该手机号对应的员工
     *
     * @param phone  手机号
     * @param siteId 站点id
     * @return 手机号对应的员工
     */
    private List<EmpInfoDO> listByPhone(String phone, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("phone", phone)
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoListVO> screenEmp(EmpInfoScreenDTO empInfoScreenDTO, TokenUser tokenUser) {
        ParamException.notNull(empInfoScreenDTO.getCompanyId(), "公司id不能为空");

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", empInfoScreenDTO.getCompanyId())
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        example.selectProperties("id", "name", "userId", "idCard", "phone", "postType", "status");

        example.orderBy("gmtCreate").desc().orderBy("id").desc();
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        empInfoList = empInfoList.stream()
                .filter(empInfo -> {
                    if (!empInfoScreenDTO.getIsAllEmp()) {
                        // 在职员工
                        if (2 != empInfo.getStatus() && 3 != empInfo.getStatus()) {
                            return false;
                        }
                        // 选择的员工
                        if (empInfoScreenDTO.getEmpIds() != null
                                && empInfoScreenDTO.getEmpIds().length > 0) {
                            if (!Arrays.asList(empInfoScreenDTO.getEmpIds()).contains(empInfo.getId())) {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    }

                    if (!empInfoScreenDTO.getAllPostType()) {
                        // 选择的员工岗位类型
                        if (empInfoScreenDTO.getPostTypes() != null
                                && empInfoScreenDTO.getPostTypes().length > 0) {
                            if (!Arrays.asList(empInfoScreenDTO.getPostTypes()).contains(empInfo.getPostType())) {
                                return false;
                            }
                        } else {
                            return false;
                        }
                    }
                    // 所有条件都满足
                    return StringUtils.isNotEmpty(empInfo.getId());
                }).collect(Collectors.toList());

        // 转vo返回
        return getVoListByDoList(empInfoList);
    }

    @Override
    public String necessary(EmpAllInfoDTO empAllInfoDTO, EmpInfoDO empInfoDO, String siteId) {
        CompanyEmpNecessaryQuery companyEmpNecessaryQuery = new CompanyEmpNecessaryQuery();
        companyEmpNecessaryQuery.setCompanyId(empInfoDO.getCompanyId());
        companyEmpNecessaryQuery.setIsNecessary(true);
        List<CompanyEmpNecessaryDO> companyEmpNecessaryDOS = companyEmpNecessaryService.selectDO(companyEmpNecessaryQuery, siteId);
        List<CompanyEmpNecessaryDO> list = new ArrayList<>();
        companyEmpNecessaryDOS.forEach(bean -> {
            CompanyEmpNecessaryDO companyEmpNecessaryDO = new CompanyEmpNecessaryDO();
            if (bean.getIsNecessary()) {
                Integer necessary = this.isNecessary(bean.getModuleCode(), empAllInfoDTO);
                if (necessary != 0) {
                    companyEmpNecessaryDO.setModuleName(bean.getModuleName());
                    list.add(companyEmpNecessaryDO);
                }
            }
        });
        StringBuffer stringBuffer = new StringBuffer();
        if (!CollectionUtils.isEmpty(list)) {
            for (CompanyEmpNecessaryDO companyEmpNecessary : list) {
                if (!StringUtils.isEmpty(companyEmpNecessary.getModuleName())) {
                    if (StringUtils.isEmpty(stringBuffer)) {
                        stringBuffer.append(companyEmpNecessary.getModuleName());
                    } else {
                        stringBuffer.append(",").append(companyEmpNecessary.getModuleName());
                    }
                }
            }
        }
        if (StringUtils.isEmpty(stringBuffer)) {
            return "";
        } else {
            return "请补全必填项" + stringBuffer.toString() + "后才能提交";
        }
    }

    private Integer isNecessary(String moduleCode, EmpAllInfoDTO empAllInfoDTO) {
        List<String> list = new ArrayList<>();
        //基本信息
        if ("basic".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getName())
                    || StringUtils.isEmpty(empAllInfoDTO.getIdCard())
                    || empAllInfoDTO.getGender() == null
                    || empAllInfoDTO.getBirthday() == null
                    || empAllInfoDTO.getMaritalStatus() == null
                    || StringUtils.isEmpty(empAllInfoDTO.getNation())
                    || empAllInfoDTO.getPoliticalStatus() == null
                    || empAllInfoDTO.getRegType() == null
                    || StringUtils.isEmpty(empAllInfoDTO.getNativeLocation())
                    || empAllInfoDTO.getBloodGroup() == null
                    || empAllInfoDTO.getBirthStatus() == null) {
                list.add("1");
            }
        }
        //联系信息
        if ("contact".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getPhone())
                    || StringUtils.isEmpty(empAllInfoDTO.getEmail())
                    || StringUtils.isEmpty(empAllInfoDTO.getCurrentLocation())) {
                list.add("1");
            }
        }
        //家庭成员
        if ("empFamily".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpFamilyList())) {
                empAllInfoDTO.getEmpFamilyList().stream().anyMatch(empInfo -> {
                    if (StringUtils.isEmpty(empInfo.getName())
                            || StringUtils.isEmpty(empInfo.getRelation())
                            || StringUtils.isEmpty(empInfo.getPhone())
                            || StringUtils.isEmpty(empInfo.getWorkUnit())) {
                        list.add("1");
                        return true;
                    }
                    return false;
                });
            } else {
                list.add("1");
            }
        }
        //紧急联系人
        if ("empContacts".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpContactsList())) {
                empAllInfoDTO.getEmpContactsList().stream().anyMatch(empInfo -> {
                    if (StringUtils.isEmpty(empInfo.getName())
                            || StringUtils.isEmpty(empInfo.getRelation())
                            || StringUtils.isEmpty(empInfo.getPhone())
                            || StringUtils.isEmpty(empInfo.getAddress())) {
                        list.add("1");
                        return true;
                    }
                    return false;
                });
            } else {
                list.add("1");
            }
        }
        //教育经历
        if ("empEducation".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpEducationList())) {
                empAllInfoDTO.getEmpEducationList().stream().anyMatch(empInfo -> {
                    if (empInfo.getEducation() == null
                            || StringUtils.isEmpty(empInfo.getGraCollege())
                            || StringUtils.isEmpty(empInfo.getMajor())
                            || empInfo.getStartTime() == null
                            || empInfo.getEndTime() == null
                            || StringUtils.isEmpty(empInfo.getTeaMethods())
                            || StringUtils.isEmpty(empInfo.getGraCerNumber())
                            || empInfo.getDegreeType() == null
                            || StringUtils.isEmpty(empInfo.getDegreeName())
                            || StringUtils.isEmpty(empInfo.getDegreeNumber())
                            || StringUtils.isEmpty(empInfo.getEducationRemark())) {
                        list.add("1");
                        return true;
                    }
                    return false;
                });
            } else {
                list.add("1");
            }
        }
        //工作经历
        if ("empWork".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpWorkList())) {
                empAllInfoDTO.getEmpWorkList().stream().anyMatch(empInfo -> {
                    if (StringUtils.isEmpty(empInfo.getCompany())
                            || StringUtils.isEmpty(empInfo.getPosition())
                            || empInfo.getStartTime() == null
                            || empInfo.getEndTime() == null
                            || StringUtils.isEmpty(empInfo.getWitName())
                            || StringUtils.isEmpty(empInfo.getWitPhone())
                            || StringUtils.isEmpty(empInfo.getLeaveReason())
                            || empInfo.getLeaveSalary() == null
                            || StringUtils.isEmpty(empInfo.getRemark())) {
                        list.add("1");
                        return true;
                    }
                    return false;
                });
            } else {
                list.add("1");
            }
        }
        //培训经历
        if ("empTrain".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpTrainList())) {
                empAllInfoDTO.getEmpTrainList().stream().anyMatch(empInfo -> {
                    if (StringUtils.isEmpty(empInfo.getTrainCourse())
                            || StringUtils.isEmpty(empInfo.getTrainOrgName())
                            || empInfo.getStartTime() == null
                            || empInfo.getEndTime() == null
                            || StringUtils.isEmpty(empInfo.getAssessResult())
                            || StringUtils.isEmpty(empInfo.getTrainCerName())
                            || StringUtils.isEmpty(empInfo.getTrainCerNumber())
                            || StringUtils.isEmpty(empInfo.getRemake())) {
                        list.add("1");
                        return true;
                    }
                    return false;
                });
            } else {
                list.add("1");
            }
        }
        //工资卡信息//开户城市和开户城市id
        if ("bank".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getBankCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankName())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankPlace())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankPlaceId())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankCardBranch())) {
                list.add("1");
            }
        }
        //附件材料//学历证明annexDegree
        if ("annex".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getAnnexPersonPhoto())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexIdCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexDegree())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexHousehold())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexSalaryCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexSocCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexPfCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexPractising())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexReward())) {
                list.add("1");
            }
        }
        return list.size();
    }


    //新版本的必填
    private List<String> isNecessaryV2(String moduleCode, EmpAllInfoDTO empAllInfoDTO, TokenUser tokenUser) throws Exception {
        List<String> list = new ArrayList<>();
        EmpInfoDO empInfoDO = selectDOById(empAllInfoDTO.getId(), tokenUser.getSiteId());
        CompanyNecessaryFieldQuery companyNecessaryFieldQuery = new CompanyNecessaryFieldQuery();
        companyNecessaryFieldQuery.setCompanyId(empInfoDO.getCompanyId());
        companyNecessaryFieldQuery.setIsNecessary(true);
        companyNecessaryFieldQuery.setFieldCode(moduleCode);
        List<CompanyNecessaryFieldListVO> companyNecessaryFieldListVOList =
                companyNecessaryFieldService.select(companyNecessaryFieldQuery, tokenUser);
        //基本信息
        if ("basic".equals(moduleCode)) {
            Map<String, Object> map = objectToMap(empAllInfoDTO);
            //判断每个必填项
            for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                        "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                    list.add(companyNecessaryFieldListVO.getFieldName());
                }
            }
            //循环查看额外的字段的是否必填
            for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalBasicList()) {
                CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                        companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                if (companyAdditionalFieldsDO.getIsNecessary() &&
                        StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                    list.add(companyAdditionalFieldsDO.getFieldName());
                }
            }
        }
        //联系信息
        if ("contact".equals(moduleCode)) {
            Map<String, Object> map = objectToMap(empAllInfoDTO.getEmpContactsList());
            //判断每个必填项
            for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                        "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                    list.add(companyNecessaryFieldListVO.getFieldName());
                }
            }
            //循环查看额外的字段的是否必填
            for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalContactsList()) {
                CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                        companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                if (companyAdditionalFieldsDO.getIsNecessary() &&
                        StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                    list.add(companyAdditionalFieldsDO.getFieldName());
                }
            }
        }
        //家庭成员
        if ("empFamily".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpFamilyList())) {
                for (EmpFamilyDTO empFamilyDTO : empAllInfoDTO.getEmpFamilyList()) {
                    Map<String, Object> map = objectToMap(empFamilyDTO);
                    //判断每个必填项
                    for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                        if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                                "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                            list.add(companyNecessaryFieldListVO.getFieldName());
                        }
                    }
                    //循环查看额外的字段的是否必填
                    for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalFamilyList()) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                                companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                        if (companyAdditionalFieldsDO.getIsNecessary() &&
                                StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                            list.add(companyAdditionalFieldsDO.getFieldName());
                        }
                    }
                }
            } else {
                list.add("家庭成员");
            }
        }
        //联系人
        if ("empContacts".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpContactsList())) {
                for (EmpContactsDTO empContactsDTO : empAllInfoDTO.getEmpContactsList()) {
                    Map<String, Object> map = objectToMap(empContactsDTO);
                    //判断每个必填项
                    for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                        if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                                "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                            list.add(companyNecessaryFieldListVO.getFieldName());
                        }
                    }
                    //循环查看额外的字段的是否必填
                    for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalContactsList()) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                                companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                        if (companyAdditionalFieldsDO.getIsNecessary() &&
                                StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                            list.add(companyAdditionalFieldsDO.getFieldName());
                        }
                    }
                }
            } else {
                list.add("紧急联系人");
            }
        }
        //教育经历
        if ("empEducation".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpEducationList())) {
                for (EmpEducationDTO empEducationDTO : empAllInfoDTO.getEmpEducationList()) {
                    Map<String, Object> map = objectToMap(empEducationDTO);
                    //判断每个必填项
                    for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                        if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                                "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                            list.add(companyNecessaryFieldListVO.getFieldName());
                        }
                    }
                    //循环查看额外的字段的是否必填
                    for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalEducationList()) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                                companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                        if (companyAdditionalFieldsDO.getIsNecessary() &&
                                StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                            list.add(companyAdditionalFieldsDO.getFieldName());
                        }
                    }
                }
            } else {
                list.add("教育经历");
            }
        }
        //工作经历
        if ("empWork".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpWorkList())) {
                for (EmpWorkDTO empWorkDTO : empAllInfoDTO.getEmpWorkList()) {
                    Map<String, Object> map = objectToMap(empWorkDTO);
                    //判断每个必填项
                    for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                        if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                                "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                            list.add(companyNecessaryFieldListVO.getFieldName());
                        }
                    }
                    //循环查看额外的字段的是否必填
                    for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalWorkList()) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                                companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                        if (companyAdditionalFieldsDO.getIsNecessary() &&
                                StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                            list.add(companyAdditionalFieldsDO.getFieldName());
                        }
                    }
                }
            } else {
                list.add("工作经历");
            }
        }
        //培训经历
        if ("empTrain".equals(moduleCode)) {
            if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpTrainList())) {
                for (EmpTrainDTO empTrainDTO : empAllInfoDTO.getEmpTrainList()) {
                    Map<String, Object> map = objectToMap(empTrainDTO);
                    //判断每个必填项
                    for (CompanyNecessaryFieldListVO companyNecessaryFieldListVO : companyNecessaryFieldListVOList) {
                        if (map.get(companyNecessaryFieldListVO.getFieldCode()) == null ||
                                "".equals(map.get(companyNecessaryFieldListVO.getFieldCode()))) {
                            list.add(companyNecessaryFieldListVO.getFieldName());
                        }
                    }
                    //循环查看额外的字段的是否必填
                    for (EmpAdditionalFieldsUpdateDTO empAdditionalFieldsUpdateDTO : empAllInfoDTO.getEmpAdditionalTrainList()) {
                        CompanyAdditionalFieldsDO companyAdditionalFieldsDO =
                                companyAdditionalFieldsService.selectByIdNoSite(empAdditionalFieldsUpdateDTO.getFieldId());
                        if (companyAdditionalFieldsDO.getIsNecessary() &&
                                StringUtils.isEmpty(empAdditionalFieldsUpdateDTO.getContent())) {
                            list.add(companyAdditionalFieldsDO.getFieldName());
                        }
                    }
                }
            } else {
                list.add("培训经历");
            }
        }
        //工资卡信息//开户城市和开户城市id
        if ("bank".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getBankCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankName())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankPlace())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankPlaceId())
                    || StringUtils.isEmpty(empAllInfoDTO.getBankCardBranch())) {
                list.add("工资卡信息//开户城市和开户城市id");
            }
        }
        //附件材料//学历证明annexDegree
        if ("annex".equals(moduleCode)) {
            if (StringUtils.isEmpty(empAllInfoDTO.getAnnexPersonPhoto())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexIdCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexDegree())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexHousehold())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexSalaryCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexSocCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexPfCard())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexPractising())
                    || StringUtils.isEmpty(empAllInfoDTO.getAnnexReward())) {
                list.add("附件材料//学历证明annexDegree");
            }
        }
        return list;
    }

    public static Map<String, Object> objectToMap(Object obj) throws IllegalAccessException {
        Map<String, Object> map = new HashMap<String, Object>();
        Class<?> clazz = obj.getClass();
        for (Field field : clazz.getDeclaredFields()) {
            field.setAccessible(true);
            String fieldName = field.getName();
            Object value = field.get(obj);
            map.put(fieldName, value);
        }
        return map;
    }

    @Override
    public String checkField(EmpAllInfoDTO empAllInfoDTO, String companyId, String siteId) {
        //拿到传入参数所有为空的字段
        Map<String, Map<String, Boolean>> typeMap = this.checkList(empAllInfoDTO);
        StringBuffer buffer = new StringBuffer();
        //查询必填字段
        CompanyNecessaryFieldQuery companyNecessaryFieldQuery = new CompanyNecessaryFieldQuery();
        companyNecessaryFieldQuery.setCompanyId(companyId);
        companyNecessaryFieldQuery.setIsNecessary(true);
        companyNecessaryFieldQuery.setIsOpen(true);
        List<CompanyNecessaryFieldDO> necessaryFieldList = companyNecessaryFieldService.selectDO(companyNecessaryFieldQuery, siteId);
        if (CollectionUtils.isEmpty(necessaryFieldList)) {
            return "";
        }
        necessaryFieldList.stream().anyMatch(necessaryField -> {
            //开始校验字段是否填写
            typeMap.keySet().forEach(key -> {
                if (key.equals(necessaryField.getModuleCode()) && !CollectionUtils.isEmpty(typeMap.get(key))) {
                    if (typeMap.get(key).get(necessaryField.getFieldCode()) != null && typeMap.get(key).get(necessaryField.getFieldCode())) {
                        buffer.append(necessaryField.getModuleName()).append(": ").append(necessaryField.getFieldName());
                    }
                }
                if ("empInfo".equals(key)) {
                    if ("basic".equals(necessaryField.getModuleCode())
                            || "contact".equals(necessaryField.getModuleCode())
                            || "bank".equals(necessaryField.getModuleCode())
                            || "annex".equals(necessaryField.getModuleCode())) {
                        if (typeMap.get(key).get(necessaryField.getFieldCode()) != null && typeMap.get(key).get(necessaryField.getFieldCode())) {
                            buffer.append(necessaryField.getModuleName()).append(": ").append(necessaryField.getFieldName());
                        }
                    }
                }
            });
            return !StringUtils.isEmpty(buffer);
        });
        if (StringUtils.isEmpty(buffer)) {
            return "";
        } else {
            return "请补全必填项" + buffer.toString() + "后才能提交";
        }
    }

    /**
     * 获取所有为空的字段集合
     *
     * @param empAllInfoDTO 传入参数
     * @return 返回字段集合
     */
    private Map<String, Map<String, Boolean>> checkList(EmpAllInfoDTO empAllInfoDTO) {
        Map<String, Map<String, Boolean>> typeMap = new HashMap<>();
        //所有的字段
        Map<String, Boolean> stringBooleanMap = this.checkObjFieldIsNull(empAllInfoDTO);
        if (!CollectionUtils.isEmpty(stringBooleanMap)) {
            typeMap.put("empInfo", stringBooleanMap);
        }
        //以下是所有list集合内的字段
        //家庭成员
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpFamilyList())) {
            empAllInfoDTO.getEmpFamilyList().forEach(bean -> {
                Map<String, Boolean> fieldIsNull = this.checkObjFieldIsNull(bean);
                if (!CollectionUtils.isEmpty(fieldIsNull)) {
                    typeMap.put("empFamily", fieldIsNull);
                }
            });
        }
        //紧急联系人
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpContactsList())) {
            empAllInfoDTO.getEmpContactsList().forEach(bean -> {
                Map<String, Boolean> contacts = this.checkObjFieldIsNull(bean);
                if (!CollectionUtils.isEmpty(contacts)) {
                    typeMap.put("empContacts", contacts);
                }
            });
        }
        //教育经历
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpEducationList())) {
            empAllInfoDTO.getEmpEducationList().forEach(bean -> {
                Map<String, Boolean> education = this.checkObjFieldIsNull(bean);
                if (!CollectionUtils.isEmpty(education)) {
                    typeMap.put("empEducation", education);
                }
            });
        }
        //工作经历
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpWorkList())) {
            empAllInfoDTO.getEmpWorkList().forEach(bean -> {
                Map<String, Boolean> empWork = this.checkObjFieldIsNull(bean);
                if (!CollectionUtils.isEmpty(empWork)) {
                    typeMap.put("empWork", empWork);
                }
            });
        }
        //培训经历
        if (!CollectionUtils.isEmpty(empAllInfoDTO.getEmpTrainList())) {
            empAllInfoDTO.getEmpTrainList().forEach(bean -> {
                Map<String, Boolean> train = this.checkObjFieldIsNull(bean);
                if (!CollectionUtils.isEmpty(train)) {
                    typeMap.put("empTrain", train);
                }
            });
        }
        return typeMap;
    }

    /**
     * 判断实体类里的所有属性不为null并且不为空串和空白
     *
     * @param obj 实体
     * @return 为空的字段集合，返回true证明为空
     */
    private Map<String, Boolean> checkObjFieldIsNull(Object obj) {
        try {
            Map<String, Boolean> map = new HashMap<>();
            List<Field> fieldList = new ArrayList<>();
            Class tempClass = obj.getClass();
            while (tempClass != null) {
                //是否还有父类
                fieldList.addAll(Arrays.asList(tempClass.getDeclaredFields()));
                tempClass = tempClass.getSuperclass();
            }
            for (Field f : fieldList) {
                f.setAccessible(true);
                if (!"serialVersionUID".equals(f.getName())) {
                    //将序列化字段去掉
                    if (f.get(obj) == null || StringUtils.isBlank(f.get(obj) + "")) {
                        map.put(f.getName(), true);
                    }
                }
            }
            return map;
        } catch (Exception e) {
            e.printStackTrace();
            throw new ParamException(e.toString());
        }
    }

    @Override
    public List<String> getSiteIdListByPhone(String phone, TokenUser tokenUser) {
        return empInfoDAO.getSiteIdListByPhone(phone);
    }

    @Override
    public List<SiteListVO> getSiteListVOByPhone(String phone, TokenUser tokenUser) {
        List<String> siteIdList = getSiteIdListByPhone(phone, tokenUser);
        if (!CollectionUtils.isEmpty(siteIdList)) {
            List<SiteDO> siteList = adminProviderService.selectByIds(Collections.singletonList(""));
            if (!CollectionUtils.isEmpty(siteList)) {
                return siteList.parallelStream()
                        .map(site -> site.to(SiteListVO.class))
                        .collect(Collectors.toList());
            }
        }
        return new ArrayList<>();
    }

    @Override
    public WeChatSiteBindVO checkBindByUnionId(String unionId, TokenUser tokenUser) {
        WeChatSiteBindVO weChatSiteBindVO = new WeChatSiteBindVO();
        // 验证unionId是否已绑定在其他员工
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("unionId", unionId)
                .andEqualTo("valid", true)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue());
        example.selectProperties("id", "name", "idCard", "phone", "siteId");
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoList)) {
            // 微信unionId未绑定过员工
            weChatSiteBindVO.setBindStatus(0);
        } else {
            // 微信unionId已绑定过员工
            weChatSiteBindVO.setBindStatus(1);
            EmpInfoDO empInfoDO = empInfoList.get(0);
            String siteName = permissionProviderService.getSiteName(empInfoDO.getSiteId());
            SiteDO siteDO = new SiteDO();
            siteDO.setName(siteName);
            weChatSiteBindVO.setPhone(empInfoDO.getPhone());
            weChatSiteBindVO.setSiteDO(siteDO);
        }
        return weChatSiteBindVO;
    }

    @Override
    public List<String> listEmpUserIdByCompany(String companyId, String siteId) {
        List<EmpInfoDO> empInfoList = listOnJobByCompanyId(companyId, siteId);

        if (CollectionUtils.isEmpty(empInfoList)) {
            return null;
        }

        return empInfoList.parallelStream()
                .filter(empInfo -> StringUtils.isNotEmpty(empInfo.getUserId()))
                .map(EmpInfoDO::getUserId).collect(Collectors.toList());
    }

    @Override
    public List<String> listEmpIdByCompany(String companyId, String siteId) {
        return empInfoDAO.listEmpIdByCompany(companyId, siteId);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer pinyin(TokenUser tokenUser) {
        EmpInfoQuery empInfoQuery = new EmpInfoQuery();
        List<EmpInfoListVO> select = select(empInfoQuery, tokenUser);
        List<EmpInfoDO> list = new ArrayList<>();
        for (EmpInfoListVO empInfo : select) {
            EmpInfoDO empInfoDO = new EmpInfoDO();
            empInfoDO.setId(empInfo.getId());
            empInfoDO.setNamePinyin(PinyinKit.nameToPinyin(empInfo.getName()));
            list.add(empInfoDO);
        }
        return empInfoDAO.updatePinyin(list, new Date(), tokenUser.getUserId());
    }

    @Override
    public EmpInfoDO getEmpInfoByCompanyAndUser(String companyId, String userId, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("companyId", companyId)
                .andEqualTo("userId", userId)
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);

        // 员工状态（1：待入职，2：入职，3：待离职，4：离职）
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());

        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public List<EmpInfoDO> listEmpInfoByIds(String siteId, String... empIds) {
        if (empIds == null || empIds.length == 0) {
            return null;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("id", Arrays.asList(empIds))
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpReduceInfoVO> listEmpReduceAndDepInfo(String companyId, String siteId) {
        List<EmpReduceInfoVO> empList = empInfoDAO.listEmpReduceAndDepInfo(companyId, siteId);
        if (CollectionUtils.isEmpty(empList)) {
            return new ArrayList<>();
        }
        return empList.stream()
                .filter(empInfo -> {
                    // dep 的isvalid是null,但name不是null,是被删除的,筛选掉
                    return empInfo.getDepIsValid() != null || !StringUtils.isNotEmpty(empInfo.getDepName());
                }).collect(Collectors.toList());
    }

    @Override
    public List<EmpReduceInfoVO> listEmpReduceAndPositionInfo(String companyId, String siteId) {
        List<EmpReduceInfoVO> positionList = empInfoDAO.listEmpReduceAndPositionInfo(companyId, siteId);
        if (CollectionUtils.isEmpty(positionList)) {
            return new ArrayList<>();
        }
        return positionList.stream()
                .filter(positionInfo -> {
                    // position 的isvalid是null,但name不是null,是被删除的,筛选掉
                    return positionInfo.getPositionIsValid() != null
                            || !StringUtils.isNotEmpty(positionInfo.getPositionName());
                }).collect(Collectors.toList());
    }

    @Override
    public List<EmpReduceInfoVO> listDepEmpInfo(String companyId, String siteId) {
        List<EmpReduceInfoVO> empDepList = empInfoDAO.listDepEmpInfo(companyId, siteId);
        if (CollectionUtils.isEmpty(empDepList)) {
            return new ArrayList<>();
        }
        // 员工与部门的关系,<empId,对应的部门>
        Map<String, List<EmpReduceInfoVO>> empDepMap = getEmpDepMap(companyId, siteId);

        // 员工与岗位的关系,<empId,对应的岗位>
        Map<String, List<EmpReduceInfoVO>> empPositionMap = getEmpPositionMap(companyId, siteId);

        // 需要展示一个人员全部部门,岗位,将每一条上加上员工所属部门和岗位
        empDepList.parallelStream().forEach(
                empInfo -> {
                    // 部门
                    String depNames = getDepNameByEmpId(empInfo.getId(), empDepMap);
                    empInfo.setDepName(depNames);
                    // 岗位
                    String positionNames = getPositionNameByEmpId(empInfo.getId(), empPositionMap);
                    empInfo.setPositionName(positionNames);
                }
        );

        return empDepList;
    }

    /**
     * 获取员工对应的部门map,<empId,对应的部门>
     *
     * @param companyId 公司id
     * @param siteId    站点id
     * @return 员工对应的部门map
     */
    @Override
    public Map<String, List<EmpReduceInfoVO>> getEmpDepMap(String companyId, String siteId) {
        Map<String, List<EmpReduceInfoVO>> empDepMap = new HashMap<>();
        List<EmpReduceInfoVO> empDepList = empInfoDAO.listEmpReduceAndDepInfo(companyId, siteId);

        if (!CollectionUtils.isEmpty(empDepList)) {
            // 根据员工id分组
            return empDepList.parallelStream()
                    .filter(empInfo -> empInfo.getDepIsValid() != null && empInfo.getDepIsValid())
                    .collect(Collectors.groupingBy(EmpReduceInfoVO::getId));

        }
        return empDepMap;
    }

    /**
     * 获取员工对应的岗位map,<empId,对应的岗位>
     *
     * @param companyId 公司id
     * @param siteId    站点id
     * @return 员工对应的岗位map
     */
    @Override
    public Map<String, List<EmpReduceInfoVO>> getEmpPositionMap(String companyId, String siteId) {
        Map<String, List<EmpReduceInfoVO>> empPositionMap = new HashMap<>();
        List<EmpReduceInfoVO> empPositionList = empInfoDAO.listEmpReduceAndPositionInfo(companyId, siteId);

        if (!CollectionUtils.isEmpty(empPositionList)) {
            // 根据员工id分组
            return empPositionList.parallelStream()
                    .filter(empInfo -> empInfo.getPositionIsValid() != null && empInfo.getPositionIsValid())
                    .collect(Collectors.groupingBy(EmpReduceInfoVO::getId));
        }
        return empPositionMap;
    }

    @Override
    public List<EmpReduceInfoVO> listDepEmpInfoByCondition(EmpReduceQuery empReduceQuery, String companyId, TokenUser tokenUser) {
        // 全部部门的员工
        List<EmpReduceInfoVO> empDepList = listDepEmpInfo(companyId, tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(empDepList)) {
            return new ArrayList<>();
        }
        // 根据条件筛选
        empDepList = filterByCondition(empDepList, companyId, empReduceQuery, tokenUser);
        return empDepList;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void updateEmpUserIdById(String empId, String userId) {
        ParamException.hasText(empId, "员工id不能为空");
        ParamException.hasText(userId, "用户id不能为空");

        EmpInfoDO empUp = new EmpInfoDO();
        empUp.setId(empId);
        empUp.setUserId(userId);
        empInfoDAO.updateByPrimaryKeySelective(empUp);
    }

    @Override
    public EmpInfoDO selectEmpByUserId(TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("userId", tokenUser.getUserId())
                .andEqualTo("siteId", tokenUser.getSiteId());
        example.setOrderByClause("FIELD(status,'2','3','1','4'), gmt_create desc");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public List<EmpInfoDO> selectByUserIds(List<String> userIds) {
        if (CollectionUtils.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("userId", userIds);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByCompanyIdsNotValid(List<String> companyIds) {
        if (CollectionUtils.isEmpty(companyIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("companyId", companyIds);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByCompanyIdsAndUserIdsNotValid(List<String> companyIds, List<String> userIds) {
        if (CollectionUtils.isEmpty(companyIds)) {
            return new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(userIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("companyId", companyIds)
                .andIn("userId", userIds);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public EmpInfoDO selectByUserId(String userId, String companyId, String siteId) {

        return selectByUserIdAndCompanyId(userId, companyId);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public String empChangeCompanyId(EmpChangeCompanyDTO empChangeCompanyDTO, TokenUser tokenUser) {
        // 查询原有员工信息
        String oldEmpId = empChangeCompanyDTO.getEmpId();
        EmpInfoDO oldEmpInfoDO = selectDOById(oldEmpId, tokenUser.getSiteId());
        ParamException.notNull(oldEmpInfoDO, "未查询到员工更换前信息，请刷新后重试");
        // 手机号在其他用工单位的非离职列表
        EmpInfoDO otherEmpInfoDO = selectOnJobByPhoneExcludeCompanyId(oldEmpInfoDO.getCompanyId(),
                oldEmpInfoDO.getPhone(), tokenUser.getSiteId());
        ParamException.isTrue(otherEmpInfoDO == null, "员工的手机号在其他用工单位的非离职列表");
        ParamException.notNull(oldEmpInfoDO.getIdCard(), "员工：" + oldEmpInfoDO.getName() + "身份证号为空，无法更换用工单位");
        // 身份证号相同的员工
        otherEmpInfoDO = selectOnJobEmpByIdCard(empChangeCompanyDTO.getCurrentCompanyId(), oldEmpInfoDO.getIdCard(), tokenUser);
        ParamException.isTrue(otherEmpInfoDO == null, "员工的身份证号在目标用工单位的非离职列表");
        // 根据原有员工的状态 决定新员工的状态
        if (oldEmpInfoDO.getStatus() != null && oldEmpInfoDO.getStatus() == 1) {
            empChangeCompanyDTO.setCurrentStatus(1);
        } else {
            empChangeCompanyDTO.setCurrentStatus(2);
        }
        // 原有员工离职
        String errorString = empChangesService.leavePositionAndEntry(empChangeCompanyDTO, tokenUser);
        // 不社保减员的话没有走减员接口需要手动把参保管理里面的减员状态修改
        String dateStr = DateUtils.getYearMonthStr(empChangeCompanyDTO.getPreQuitDate());
        List<String> monthIdList = empSocMonthService.selectMonthIdListAfterAndEqualsDate
                (empChangeCompanyDTO.getCompanyId(), dateStr, tokenUser.getSiteId());
        empSocInfoService.updateWhetherLeave(Collections.singletonList(oldEmpId),
                true, monthIdList, tokenUser);
        if (errorString != null) {
            return errorString;
        }
        // 离职后的员工信息
        oldEmpInfoDO = selectDOById(oldEmpId, tokenUser.getSiteId());
        onJobRecordService.saveLeaveDate(oldEmpId, oldEmpInfoDO.getCompanyId(), oldEmpInfoDO.getJoinDate()
                , oldEmpInfoDO.getTurnStraightDate(), oldEmpInfoDO.getLeaveDate(), tokenUser);

//        // 恢复用户信息
//        userProviderService.recoverUser(oldEmpInfoDO.getUserId(), tokenUser);
        // 判断员工是否在转入公司就职过 如果就职 调用恢复在职方法
        EmpInfoDO resignEmpInfoDO = selectResignedByCompanyIdAndIdCard(empChangeCompanyDTO.getCurrentCompanyId(), oldEmpInfoDO.getIdCard());
        //预登记同步员工状态
        CheckInPeopleQuery checkInPeopleQuery = new CheckInPeopleQuery();
        checkInPeopleQuery.setPhone(oldEmpInfoDO.getPhone());
        checkInPeopleQuery.setSource("预登记");
        List<CheckInPeopleListVO> select = checkInPeopleService.select(checkInPeopleQuery, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(select)) {
            CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
            checkInPeopleUpdateDTO.setId(select.get(0).getId());
            checkInPeopleUpdateDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
            checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
        }
        // 入职新用工单位 创建新员工
        String resignEmpId = null;
        if (resignEmpInfoDO != null) {
            resignEmpId = resignEmpInfoDO.getId();
        }
        empSocInfoService.updateWhetherLeave(Collections.singletonList(resignEmpId), false, null, tokenUser);
        EmpInfoDO empInfoDO = saveOrUpdateEmpInfo(empChangeCompanyDTO, oldEmpInfoDO, resignEmpId, tokenUser);
        EmpInfoVO empInfoVO = empInfoDO.to(EmpInfoVO.class);
        onJobRecordService.saveJoinDate(empInfoDO.getId(), empInfoDO.getCompanyId(), empInfoDO.getJoinDate()
                , empInfoDO.getTurnStraightDate(), tokenUser);
        // 同步其他信息
        synchronizeOtherInformation(empInfoVO, oldEmpInfoDO.getId(), oldEmpInfoDO.getCompanyId(), tokenUser);
        try {
            OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
            operationEmpRecordAddDTO.setEmpId(empInfoDO.getId());
            operationEmpRecordAddDTO.setEmpStatus(3);
            operationEmpRecordAddDTO.setQueryType(2);
            operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
            operationEmpRecordAddDTO.setUserId(empInfoDO.getUserId());
            operationEmpRecordAddDTO.setSourceType(3);
            operationEmpRecordAddDTO.setCompanyId(empInfoDO.getCompanyId());
            operationEmpRecordAddDTO.setSourceTypeInfo("更换用工单位");
            operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoServiceImpl.empChangeCompanyId");
            operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
        } catch (Exception e) {
            log.error("员工记录异常");
        }
        return null;
    }

    /**
     * 创建、更新员工信息
     *
     * @param empChangeCompanyDTO 员工入职新公司信息
     * @param oldEmpInfoDO        员工个人信息
     * @param resignEmpId         新公司离职员工Id（不为空则说明在离职列表）
     * @param tokenUser           当前用户
     * @return 员工新信息
     */
    private EmpInfoDO saveOrUpdateEmpInfo(EmpChangeCompanyDTO empChangeCompanyDTO, EmpInfoDO oldEmpInfoDO
            , String resignEmpId, TokenUser tokenUser) {
        String oldEmpInfoId = oldEmpInfoDO.getId();
        // 创建新员工  原有信息全部考入
        String oldCompanyId = oldEmpInfoDO.getCompanyId();
        EmpInfoDO empInfoDO = oldEmpInfoDO.to(EmpInfoDO.class);
        // 页面输入信息
        empInfoDO.setPostType(empChangeCompanyDTO.getCurrentPostType());
        empInfoDO.setJoinDate(empChangeCompanyDTO.getCurrentJoinDate());
        empInfoDO.setJoinCityCode(empChangeCompanyDTO.getCurrentJoinCityCode());
        empInfoDO.setFormalType(empChangeCompanyDTO.getCurrentFormalType());
        empInfoDO.setTurnStraightDate(empChangeCompanyDTO.getCurrentTurnStraightDate());
        empInfoDO.setCompanyId(empChangeCompanyDTO.getCurrentCompanyId());
        empInfoDO.setEmployType(empChangeCompanyDTO.getCurrentEmployType());
        empInfoDO.setStatus(empChangeCompanyDTO.getCurrentStatus());
        empInfoDO.setJoinCityName(empChangeCompanyDTO.getCurrentJoinCityName());
        empInfoDO.setPreJoinDate(empChangeCompanyDTO.getCurrentPreJoinDate());
        empInfoDO.setPreJoinDep(empChangeCompanyDTO.getCurrentPreJoinDep());
        empInfoDO.setPreJoinPosition(empChangeCompanyDTO.getCurrentPreJoinPosition());
        empInfoDO.setProbationDays(empChangeCompanyDTO.getCurrentProbationDays());
        empInfoDO.setEmpSocStatus(NOT_SOC.getValue());
        // 员工在职信息清空
        empInfoDO.setSalaryType(0);
        empInfoDO.setWorkCity(null);
        empInfoDO.setWorkCityId(null);
        empInfoDO.setWorkingUnitName(null);
        empInfoDO.setNumber(null);
        empInfoDO.setPreJoinDep(null);
        empInfoDO.setPreJoinPosition(null);
        empInfoDO.setPlanIncreaseDate(null);
        empInfoDO.setPlanStopSocDate(null);
        empInfoDO.setIncreaseDate(null);
        empInfoDO.setStopSocDate(null);
        empInfoDO.setSocProgId(null);
        empInfoDO.setLeaveDate(null);
        empInfoDO.setLeaveReason(null);
        if (resignEmpId == null) {
            empInfoDO.setId(null);
            EmpInfoDO save = save(empInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
            // 更换用工单位 入职通知
            sendNotice(empInfoDO, tokenUser);
            return save;
        }
        empInfoDO.setId(resignEmpId);
        updateById(empInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
        return empInfoDO;
    }

    /**
     * 同步其他信息
     *
     * @param empInfoVO    更换后的员工信息
     * @param oldEmpInfoId 更换前的员工Id
     * @param oldCompanyId 更换前的用工单位Id
     * @param tokenUser    当前用户
     */
    private void synchronizeOtherInformation(EmpInfoVO empInfoVO, String oldEmpInfoId, String oldCompanyId, TokenUser tokenUser) {
        String newEmpInfoId = empInfoVO.getId();
        // 家庭成员
        List<EmpFamilyDO> empFamilyDOList = empFamilyService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empFamilyDOList)) {
            empFamilyDOList.forEach(empFamilyDO -> {
                EmpFamilyAddDTO empFamilyAddDTO = empFamilyDO.to(EmpFamilyAddDTO.class);
                empFamilyAddDTO.setEmpId(newEmpInfoId);
                empFamilyService.save(empFamilyAddDTO, tokenUser);
            });
        }
        // 教育经历
        List<EmpEducationDO> empEducationDOList = empEducationService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empEducationDOList)) {
            empEducationDOList.forEach(empEducationDO -> {
                EmpEducationAddDTO empEducationAddDTO = empEducationDO.to(EmpEducationAddDTO.class);
                empEducationAddDTO.setEmpId(newEmpInfoId);
                empEducationService.save(empEducationAddDTO, tokenUser);
            });
        }
        // 工作经历
        List<EmpWorkDO> empWorkDOList = empWorkService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empWorkDOList)) {
            empWorkDOList.forEach(empWorkDO -> {
                EmpWorkAddDTO empWorkAddDTO = empWorkDO.to(EmpWorkAddDTO.class);
                empWorkAddDTO.setEmpId(newEmpInfoId);
                empWorkService.save(empWorkAddDTO, tokenUser);
            });
        }
        // 培训经历
        List<EmpTrainDO> empTrainDOList = empTrainService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empTrainDOList)) {
            empTrainDOList.forEach(empTrainDO -> {
                EmpTrainAddDTO empTrainAddDTO = empTrainDO.to(EmpTrainAddDTO.class);
                empTrainAddDTO.setEmpId(newEmpInfoId);
                empTrainService.save(empTrainAddDTO, tokenUser);
            });
        }
        // 奖惩记录
        List<EmpRewardPunishDO> empRewardPunishDOList = empRewardPunishService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        for (EmpRewardPunishDO empRewardPunishDO : empRewardPunishDOList) {
            empRewardPunishDO.setId(null);
            empRewardPunishDO.setEmpId(newEmpInfoId);
            empRewardPunishService.onlySave(empRewardPunishDO);
        }
        // 紧急联系人
        List<EmpContactsDO> empContactsDOList = empContactsService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
        for (EmpContactsDO empContactsDO : empContactsDOList) {
            empContactsDO.setId(null);
            empContactsDO.setEmpId(newEmpInfoId);
            empContactsService.onlySave(empContactsDO);
        }
        // 人事变动
        List<PersonalEventDO> personalEventDOList = personalEventService.selectDoByEmpId(oldEmpInfoId, tokenUser);
        for (PersonalEventDO personalEventDO : personalEventDOList) {
            personalEventDO.setId(null);
            personalEventDO.setEmpId(newEmpInfoId);
            personalEventService.onlySave(personalEventDO);
        }
        // 花名册合同已关联合同表 更换用工单位 不带合同
//        // 纸质合同
//        List<EmpPaperContractDO> empPaperContractList = empPaperContractService.listContractByEmpId(oldEmpInfoId, tokenUser.getSiteId());
//        for (EmpPaperContractDO empPaperContractDO : empPaperContractList) {
//            empPaperContractDO.setId(null);
//            empPaperContractDO.setEmpId(empInfoVO.getId());
//            empPaperContractService.onlySave(empPaperContractDO);
//        }
//
//        // 电子合同
//        List<EmpContractDO> empContractDOList = empContractService.listByEmpId(oldEmpInfoId, tokenUser.getSiteId());
//        for (EmpContractDO empContractDO : empContractDOList) {
//            empContractDO.setId(null);
//            empContractDO.setEmpId(empInfoVO.getId());
//            empContractService.onlySave(empContractDO);
//        }

        // 先清除现有手机号的个税信息 再从旧手机号那带过来
        List<EmpTaxGrandTotalDO> specialEmpTaxGrandTotalDOList = salaryProviderService
                .selectEmpTaxGrandTotalByEmpId(newEmpInfoId, empInfoVO.getCompanyId(), tokenUser);
        if (!CollectionUtils.isEmpty(specialEmpTaxGrandTotalDOList)) {
            salaryProviderService.deleteEmpTaxGrandTotalByIds(tokenUser, specialEmpTaxGrandTotalDOList
                    .parallelStream().map(BaseDO::getId).toArray(Long[]::new));
        }
        // 个税信息-专项附加项详情(A->B,然后B->A 先把A中的清除掉 以免索引重复)
        List<SpecialAdditionalDetailDO> newSpecialAdditionalDetailDOList = salaryProviderService
                .selectSpecialAdditionalDetailByEmpId(newEmpInfoId, tokenUser);
        // 个税信息-专项附加项详情
        List<SpecialAdditionalDetailDO> specialAdditionalDetailDOList = salaryProviderService
                .selectSpecialAdditionalDetailByEmpId(oldEmpInfoId, tokenUser);
        // 再把B中的个税信息-专项附加项详情删除掉
        newSpecialAdditionalDetailDOList.addAll(specialAdditionalDetailDOList);
        salaryProviderService.deleteSpecialAdditionalDetailByIds(tokenUser
                , newSpecialAdditionalDetailDOList.parallelStream().map(BaseDO::getId).toArray(Long[]::new));
        for (SpecialAdditionalDetailDO specialAdditionalDetailDO : specialAdditionalDetailDOList) {
            specialAdditionalDetailDO.setId(null);
            specialAdditionalDetailDO.setEmpId(newEmpInfoId);
            specialAdditionalDetailDO.setCompanyId(empInfoVO.getCompanyId());
            salaryProviderService.saveSpecialAdditionalDetail(specialAdditionalDetailDO);
        }
        List<EmpTaxGrandTotalDO> empTaxGrandTotalDOList = salaryProviderService
                .selectEmpTaxGrandTotalByEmpId(oldEmpInfoId, oldCompanyId, tokenUser);
        for (EmpTaxGrandTotalDO empTaxGrandTotalDO : empTaxGrandTotalDOList) {
            empTaxGrandTotalDO.setId(null);
            empTaxGrandTotalDO.setEmpId(newEmpInfoId);
            empTaxGrandTotalDO.setCompanyId(empInfoVO.getCompanyId());
            salaryProviderService.saveEmpTaxGrandTotal(empTaxGrandTotalDO);
        }

        // 更换社保信息
        empSocRelatedService.initRelatedByEmpId(newEmpInfoId, empInfoVO.getCompanyId(), tokenUser);
        // 用工档案 新增添加花名册记录
        String desc = PersonalEventExample.INSERT_INTO_ADMIN + tokenUser.getUserName() + PersonalEventExample.INSERT_INTO_SYS;
        personalEventService.autoSave(empInfoVO, tokenUser, desc, PersonalEventEnum.ADD.getValue(), PersonalEventEnum.ADD.getDesc());

        //更新员工的 “信息补充 未完善、已完善”
        List<String> list = new ArrayList<>();
        list.add(newEmpInfoId);
        empCompleteInfo(list, tokenUser);

    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public String empBatchChangeCompanyId(EmpBatchChangeCompanyDTO empBatchChangeCompanyDTO, TokenUser tokenUser) {
        List<EmpBatchChangeCompanyDTO.EmpInformation> empInformationList = empBatchChangeCompanyDTO.getEmpInformationList();
        ParamException.notEmpty(empInformationList, "未选中需要更换用工单位的员工");
        List<String> errorStringList = new ArrayList<>();
        for (EmpBatchChangeCompanyDTO.EmpInformation empInformation : empInformationList) {
            EmpChangeCompanyDTO empChangeCompanyDTO = empBatchChangeCompanyDTO.to(EmpChangeCompanyDTO.class);
            empChangeCompanyDTO.setEmpId(empInformation.getEmpId());
            empChangeCompanyDTO.setName(empInformation.getName());
            String errorString = null;
            try {
                errorString = empChangeCompanyId(empChangeCompanyDTO, tokenUser);
            } catch (Exception e) {
                errorStringList.add(empInformation.getName() + "：" + e.getMessage());
            }
            if (errorString != null) {
                errorStringList.add(empInformation.getName() + "：" + errorString);
            }
        }
        if (CollectionUtils.isEmpty(errorStringList)) {
            return null;
        }
        throw new ParamException(errorStringList.parallelStream().collect(Collectors.joining("，")));
    }


    @Override
    public EmpInfoDO selectEmpByIdCard(String companyId, String idCard, TokenUser tokenUser) {
        ParamException.hasText(idCard, "员工身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andEqualTo("idCard", idCard);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        } else {
            ParamException.isTrue(empInfoDOList.size() == 1, "身份证【" + idCard + "】查询到多条员工信息");
            return empInfoDOList.get(0);
        }
    }

    @Override
    public EmpInfoDO selectOnJobEmpByIdCard(String companyId, String idCard, TokenUser tokenUser) {
        ParamException.hasText(idCard, "员工身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("idCard", idCard);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        } else {
            ParamException.isTrue(empInfoDOList.size() == 1, "身份证【" + idCard + "】查询到多条员工信息");
            return empInfoDOList.get(0);
        }
    }

    @Override
    public List<EmpInfoDO> selectEmpByIdCardList(String companyId, List<String> idCardList, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);

        return empInfoDAO.selectByExample(example);
    }

    @Override
    public EmpInfoDO selectEmpByIdCardAllStatus(String companyId, String idCard, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andEqualTo("idCard", idCard);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        } else {
            return empInfoDOList.get(0);
        }
    }

    @Override
    public List<EmpInfoDO> selectOnJobByCompanyIdAndEmpIdList(String companyId, List<String> empIdList, String nameOrPhone,
                                                              TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        if (StringUtils.isNotEmpty(nameOrPhone)) {
            example.and().andLike("name", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }

        if (!CollectionUtils.isEmpty(empIdList)) {
            example.and().andIn("id", empIdList);
        }
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByCompanyIdAndEmpIdList(String companyId, List<String> empIdList, String nameOrPhone,
                                                         Integer status, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId);
        if (StringUtils.isNotEmpty(nameOrPhone)) {
            example.and().orLike("name", "%" + nameOrPhone + "%")
                    .orLike("idCard", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }

        if (!CollectionUtils.isEmpty(empIdList)) {
            example.and().andIn("id", empIdList);
        }
        if (Objects.nonNull(status)) {
            example.and().andEqualTo("status", status);
        }
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public EmpInfoDO selectOnJobByUserIdAndSiteId(String userId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("userId", userId);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public EmpInfoDO selectResignedByCompanyIdAndEmpId(String companyId, String empId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("id", empId)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue());
        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public EmpInfoDO selectResignedByCompanyIdAndIdCard(String companyId, String idCard) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("idCard", idCard)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue());
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public Page<EmpInfoDO> pageByFill(EmpSocPageQuery empSocPageQuery, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("companyId", empSocPageQuery.getCompanyId())
                .andEqualTo("siteId", siteId)
                .andNotEqualTo("status", 1)
                .andEqualTo("postType", empSocPageQuery.getPostType());
        if (!StringUtils.isEmpty(empSocPageQuery.getNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + empSocPageQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + empSocPageQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empSocPageQuery.getNameOrPhone() + "%");
        }
        example.selectProperties("id", "name", "postType", "empSocStatus");
        return empInfoDAO.selectPageByExample(example, empSocPageQuery.getPageNo(), empSocPageQuery.getPageSize());
    }

    @Override
    public Page<EmpInfoDO> increaseSiftEmp(EmpSocPageQuery empSocPageQuery, String siteId) {
        if (StrKit.isNotEmpty(empSocPageQuery.getTag())) {
            // 标签
            empSocPageQuery.setTagList(ArrayKit.split(empSocPageQuery.getTag(), ","));
        }
        List<EmpInfoDO> empInfoDOList = empInfoDAO.increaseSiftEmp(empSocPageQuery, siteId);
        return PageKit.startPage(empInfoDOList, empSocPageQuery.getPageNo(), empSocPageQuery.getPageSize());
    }

    @Override
    public List<SiftEmpCountVO> increaseSiftEmpCount(String companyId, TokenUser tokenUser) {
        List<SiftEmpCountVO> result = new ArrayList<>();
        List<DictItemDO> list = adminProviderService.selectAllDictItem(null, POST_TYPE, tokenUser);
        Map<String, DictItemDO> dictItemDOMap = list.stream()
                .collect(Collectors.toMap(DictItemDO::getDictItemValue, v -> v));
        EmpSocPageQuery empSocPageQuery = new EmpSocPageQuery();
        empSocPageQuery.setCompanyId(companyId);
        // 全部待增
        empSocPageQuery.setNotAll(true);
        SiftEmpCountVO notAll = new SiftEmpCountVO();
        notAll.setFirstType("全部待增");
        int count = 0;
        Map<String, Integer> notAllPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            notAllPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        notAll.setPostTypeCount(notAllPostCount);
        notAll.setFirstTypeCount(count);
        result.add(notAll);
        // 无社保
        empSocPageQuery.setNotAll(null);
        empSocPageQuery.setNotSoc(true);
        count = 0;
        SiftEmpCountVO notSoc = new SiftEmpCountVO();
        notSoc.setFirstType("无社保");
        Map<String, Integer> notSocPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            notSocPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        notSoc.setPostTypeCount(notSocPostCount);
        notSoc.setFirstTypeCount(count);
        result.add(notSoc);
        // 无医保
        count = 0;
        empSocPageQuery.setNotSoc(null);
        empSocPageQuery.setNotMe(true);
        SiftEmpCountVO notMe = new SiftEmpCountVO();
        notMe.setFirstType("无医保");
        Map<String, Integer> notMePostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            notMePostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        notMe.setPostTypeCount(notMePostCount);
        notMe.setFirstTypeCount(count);
        result.add(notMe);
        // 无公积金
        count = 0;
        empSocPageQuery.setNotMe(null);
        empSocPageQuery.setNotPf(true);
        SiftEmpCountVO notPf = new SiftEmpCountVO();
        notPf.setFirstType("无公积金");
        Map<String, Integer> notPfPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            notPfPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        notPf.setPostTypeCount(notPfPostCount);
        notPf.setFirstTypeCount(count);
        result.add(notPf);
        return result;
    }

    @Override
    public Page<EmpInfoDO> decreaseSiftEmp(EmpSocPageQuery empSocPageQuery, String siteId) {
        if (StrKit.isNotEmpty(empSocPageQuery.getTag())) {
            // 标签
            empSocPageQuery.setTagList(ArrayKit.split(empSocPageQuery.getTag(), ","));
        }
        List<EmpInfoDO> empInfoDOList = empInfoDAO.decreaseSiftEmp(empSocPageQuery, siteId);
        return PageKit.startPage(empInfoDOList, empSocPageQuery.getPageNo(), empSocPageQuery.getPageSize());
    }

    @Override
    public List<SiftEmpCountVO> decreaseSiftEmpCount(String companyId, TokenUser tokenUser) {
        List<SiftEmpCountVO> result = new ArrayList<>();
        List<DictItemDO> list = adminProviderService.selectAllDictItem(null, POST_TYPE, tokenUser);
        Map<String, DictItemDO> dictItemDOMap = list.stream()
                .collect(Collectors.toMap(DictItemDO::getDictItemValue, v -> v));
        EmpSocPageQuery empSocPageQuery = new EmpSocPageQuery();
        empSocPageQuery.setCompanyId(companyId);
        // 全部待减
        empSocPageQuery.setHaveAll(true);
        SiftEmpCountVO haveAll = new SiftEmpCountVO();
        haveAll.setFirstType("全部待减");
        int count = 0;
        Map<String, Integer> haveAllPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            haveAllPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        haveAll.setPostTypeCount(haveAllPostCount);
        haveAll.setFirstTypeCount(count);
        result.add(haveAll);
        // 已缴社保
        empSocPageQuery.setHaveAll(null);
        empSocPageQuery.setHaveSoc(true);
        count = 0;
        SiftEmpCountVO haveSoc = new SiftEmpCountVO();
        haveSoc.setFirstType("已缴社保");
        Map<String, Integer> haveSocPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            haveSocPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        haveSoc.setPostTypeCount(haveSocPostCount);
        haveSoc.setFirstTypeCount(count);
        result.add(haveSoc);
        // 已缴医保
        empSocPageQuery.setHaveSoc(null);
        empSocPageQuery.setHaveMe(true);
        SiftEmpCountVO haveMe = new SiftEmpCountVO();
        haveMe.setFirstType("已缴医保");
        count = 0;
        Map<String, Integer> haveMePostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            haveMePostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        haveMe.setPostTypeCount(haveMePostCount);
        haveMe.setFirstTypeCount(count);
        result.add(haveMe);
        // 已缴公积金
        empSocPageQuery.setHaveMe(null);
        empSocPageQuery.setHavePf(true);
        SiftEmpCountVO havePf = new SiftEmpCountVO();
        havePf.setFirstType("已缴公积金");
        count = 0;
        Map<String, Integer> havePfPostCount = new HashMap<>();
        for (String postType : dictItemDOMap.keySet()) {
            DictItemDO dictItem = dictItemDOMap.get(postType);
            empSocPageQuery.setPostType(postType);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            havePfPostCount.put(dictItem.getDictItemKey(), empInfoDOList.size());
            count += empInfoDOList.size();
        }
        havePf.setPostTypeCount(havePfPostCount);
        havePf.setFirstTypeCount(count);
        result.add(havePf);
        return result;
    }

    @Override
    public EmpInfoPasteVO selectEmpGroupByIdCards(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        EmpSocPageQuery empSocPageQuery = new EmpSocPageQuery();
        empSocPageQuery.setCompanyId(companyId);
        empSocPageQuery.setIdCardList(new ArrayList<>());
        for (String idCard : idCards) {
            List<String> queryIdCardList = empSocPageQuery.getIdCardList();
            queryIdCardList.clear();
            queryIdCardList.add(idCard);
            List<EmpInfoDO> empInfoDO = empInfoDAO.increaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            if (CollectionUtils.isEmpty(empInfoDO)) {
                idCardList.add(idCard);
            } else {
                empInfoVOList.add(empInfoDO.get(0).to(EmpInfoVO.class));
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public EmpInfoPasteVO selectEmpGroupByIdCards2(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        EmpSocPageQuery empSocPageQuery = new EmpSocPageQuery();
        empSocPageQuery.setCompanyId(companyId);
        empSocPageQuery.setIdCardList(new ArrayList<>());
        for (String idCard : idCards) {
            List<String> queryIdCardList = empSocPageQuery.getIdCardList();
            queryIdCardList.clear();
            queryIdCardList.add(idCard);
            List<EmpInfoDO> empInfoDO = empInfoDAO.decreaseSiftEmp(empSocPageQuery, tokenUser.getSiteId());
            if (CollectionUtils.isEmpty(empInfoDO)) {
                idCardList.add(idCard);
            } else {
                empInfoVOList.add(empInfoDO.get(0).to(EmpInfoVO.class));
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public Page<EmpSocDetailsVO> selectEmpSocByEmpIdList(EmpSocTransformQuery empSocTransformQuery, TokenUser tokenUser) {
        PageInfo<EmpSocDetailsVO> empSocDetailsPageInfo = PageHelper.startPage(empSocTransformQuery.getPageNo(), empSocTransformQuery.getPageSize()).doSelectPageInfo(() ->
                empInfoDAO.selectEmpSocByEmpIdList(empSocTransformQuery.getEmpIdList()));
        Page<EmpSocDetailsVO> page = new Page(empSocDetailsPageInfo.getList(), empSocTransformQuery.getPageNo(),
                empSocTransformQuery.getPageSize(), (int) empSocDetailsPageInfo.getTotal());
        for (EmpSocDetailsVO entity : page.getEntities()) {
            if (INCREMENT.getValue().equals(entity.getEmpSocStatus()) ||
                    WAIT_INCREMENT.getValue().equals(entity.getEmpSocStatus())) {
                entity.setSocOrStopSocDate(entity.getPlanIncreaseDate());
            } else if (ATTRITION.getValue().equals(entity.getEmpSocStatus()) ||
                    WAIT_ATTRITION.getValue().equals(entity.getEmpSocStatus())) {

                entity.setSocOrStopSocDate(entity.getPlanStopSocDate());
            }
        }
        return page;
    }

    @Override
    public Page<EmpInfoDO> selectDifferenceEmp(EmpSocPageQuery empSocPageQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", empSocPageQuery.getCompanyId())
                .andNotEqualTo("status", 1)
                .andEqualTo("valid", true);
        if (!StringUtils.isEmpty(empSocPageQuery.getNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + empSocPageQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + empSocPageQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empSocPageQuery.getNameOrPhone() + "%");
        }
        if (!StringUtils.isEmpty(empSocPageQuery.getTag())) {
            // 标签
            List<String> tags = ArrayKit.split(empSocPageQuery.getTag(), ",");
            for (String tag : tags) {
                example.and().andCondition("FIND_IN_SET('" + tag + "' , tag)");
            }
        }
        if (!StringUtils.isEmpty(empSocPageQuery.getPostType())) {
            example.and().andEqualTo("postType", empSocPageQuery.getPostType());
        }
        if (!ObjectUtils.isEmpty(empSocPageQuery.getRegType())) {
            example.and().andEqualTo("regType", empSocPageQuery.getRegType());
        }
        if (!ObjectUtils.isEmpty(empSocPageQuery.getJoinDateStart())) {
            example.and().andBetween("joinDate", empSocPageQuery.getJoinDateStart(), empSocPageQuery.getJoinDateEnd());
        }
        example.orderBy("gmtCreate").desc();
        if (!ObjectUtils.isEmpty(empSocPageQuery.getCurrentFilter())) {
            EmpSocInfoQuery empSocInfoQuery = new EmpSocInfoQuery();
            empSocInfoQuery.setCompanyId(empSocPageQuery.getCompanyId());
            empSocInfoQuery.setMonthId(empSocPageQuery.getMonthId());
            // 不管他參數是否要筛选本账单人员，你都要查询出这个账单的所有人来
            List<EmpSocInfoListVO> empSocInfoList = empSocInfoService
                    .selectAllByMonthId(empSocInfoQuery, tokenUser);
            if (!empSocPageQuery.getCurrentFilter()) {
                if (!CollectionUtils.isEmpty(empSocInfoList)) {
                    List<String> currentEmpIdList = empSocInfoList.stream()
                            .map(EmpSocInfoListVO::getEmpId).distinct().collect(Collectors.toList());
                    example.and().andNotIn("id", currentEmpIdList);
                }
            } else {
                if (CollectionUtils.isEmpty(empSocInfoList)) {
                    return new Page<>(empSocPageQuery.getPageSize(), empSocPageQuery.getPageNo());
                }
                List<String> currentEmpIdList = empSocInfoList.stream()
                        .map(EmpSocInfoListVO::getEmpId).distinct().collect(Collectors.toList());
                example.and().andIn("id", currentEmpIdList);
            }
        }
        return empInfoDAO.selectPageByExample(example, empSocPageQuery.getPageNo(), empSocPageQuery.getPageSize());
    }

    @Override
    public EmpInfoPasteVO pasteIdCardSelect(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> notFindIdCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        Example example = new Example(EmpInfoDO.class);
        // 除了待入职都能搜到
        for (String idCard : idCards) {
            example.clear();
            example.and()
                    .andEqualTo("idCard", idCard)
                    .andEqualTo("siteId", tokenUser.getSiteId())
                    .andEqualTo("companyId", companyId)
                    .andNotEqualTo("status", 1)
                    .andEqualTo("valid", true);
            EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
            if (ObjectUtils.isEmpty(empInfoDO)) {
                notFindIdCardList.add(idCard);
            } else {
                empInfoVOList.add(empInfoDO.to(EmpInfoVO.class));
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(notFindIdCardList);
        return empInfoPasteVO;
    }

    @Override
    public List<EmpInfoDO> selectEmpBySiteIdAndCompanyIdList(List<String> companyIdList, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            example.and().andIn("companyId", companyIdList);
        }
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpPostTypeListVO> selectEmpListByPostType(String companyId, Integer formalType, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andEqualTo("formalType", formalType)
                .andIn("status", Arrays.asList(2, 3));
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExample(example);
        List<EmpInfoVO> empInfoVOList = empInfoList.stream()
                .map(empInfoDO -> empInfoDO.to(EmpInfoVO.class))
                .collect(Collectors.toList());
        Map<Integer, List<EmpInfoVO>> empTypeMap = empInfoVOList.stream().collect(Collectors.groupingBy(EmpInfoVO::getPostType));
        List<EmpPostTypeListVO> empPostTypeListVOList = new ArrayList<>();
        Arrays.stream(PostType.values()).forEach(postType -> {
            EmpPostTypeListVO empPostTypeListVO = new EmpPostTypeListVO();
            empPostTypeListVO.setTypeName(postType.getDesc());
            empPostTypeListVO.setEmpList(empTypeMap.get(postType.getValue()));
            empPostTypeListVOList.add(empPostTypeListVO);
        });
        return empPostTypeListVOList;
    }

    @Override
    public Page<EmpInfoVO> pageEmpList(EmpListQuery empListQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", empListQuery.getCompanyId())
                .andIn("status", Arrays.asList(2, 3));
        if (StringUtils.isNotBlank(empListQuery.getNameOrPhone())) {
            String nameOrPhone = empListQuery.getNameOrPhone().replaceAll("，", ",");
            String[] split = nameOrPhone.split(",");
            List<String> nameOrPhoneList = Arrays.asList(split);
            if (!CollectionUtils.isEmpty(nameOrPhoneList)) {
                // 批量查询手机号
                example.and()
                        .orLike("name", "%" + empListQuery.getNameOrPhone() + "%")
                        .orLike("idCard", "%" + empListQuery.getNameOrPhone() + "%")
                        .orLike("phone", "%" + empListQuery.getNameOrPhone() + "%")
                        .orIn("phone", nameOrPhoneList);
            } else {
                example.and()
                        .orLike("name", "%" + empListQuery.getNameOrPhone() + "%")
                        .orLike("idCard", "%" + empListQuery.getNameOrPhone() + "%")
                        .orLike("phone", "%" + empListQuery.getNameOrPhone() + "%");
            }
        }
        if (StringUtils.isNotBlank(empListQuery.getFormalType())) {
            String[] split = empListQuery.getFormalType().split(",");
            example.and().andIn("formalType", Arrays.asList(split));
        }
        if (StrKit.isNotEmpty(empListQuery.getPostType())) {
            String[] split = empListQuery.getPostType().split(",");
            example.and().andIn("postType", Arrays.asList(split));
        }
        // 高级筛选(入职日期、薪资规则id等)
        if (empListQuery.getJoinDateStart() != null && empListQuery.getJoinDateEnd() != null) {
            // 入职时间
            example.and().andBetween("joinDate", empListQuery.getJoinDateStart(), empListQuery.getJoinDateEnd());
        }
        if (StrKit.isNotEmpty(empListQuery.getSalaryRuleId())) {
            // 薪资规则id
            example.and().andEqualTo("salaryRuleId", empListQuery.getSalaryRuleId());
        }
        if (StrKit.isNotEmpty(empListQuery.getServiceFeeRuleId())) {
            // 劳务费规则id
            example.and().andEqualTo("serviceFeeRuleId", empListQuery.getServiceFeeRuleId());
        }
        if (StrKit.isNotEmpty(empListQuery.getTag())) {
            // 标签
            List<String> tags = ArrayKit.split(empListQuery.getTag(), ",");
            for (String tag : tags) {
                example.and().andCondition("FIND_IN_SET('" + tag + "' , tag)");
            }
        }
        example.selectProperties("id", "name", "phone", "empPhoto", "idCard", "postType");
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, empListQuery.getPageNo(), empListQuery.getPageSize());

        return empInfoDOPage.to(EmpInfoVO.class);
    }

    @Override
    public EmpInfoPasteVO empListByIdCards(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        for (String idCard : idCards) {
            Example example = new Example(EmpInfoDO.class);
            example.and()
                    .andEqualTo("idCard", idCard)
                    .andEqualTo("companyId", companyId)
                    .andNotEqualTo("status", HAS_QUIT.getValue())
                    .andEqualTo("valid", true);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
            if (!CollectionUtils.isEmpty(empInfoDOList)) {
                EmpInfoDO empInfoDO = empInfoDOList.get(0);
                if (empInfoVOList.removeIf(empInfoVO -> empInfoVO.getId().equals(empInfoDO.getId()))) {
                    idCardList.add(idCard);
                }
                empInfoVOList.add(empInfoDO.to(EmpInfoVO.class));
            } else {
                idCardList.add(idCard);
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public List<EmpInfoDO> listByIdCardList(List<String> idCardList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(idCardList)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andIn("idCard", idCardList);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectOnJobEmpListByFormalTypeAndCompanyIdAndPostType(List<String> formalType, String companyId,
                                                                                 List<String> postType, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andIn("status", Arrays.asList(2, 3));
        if (!CollectionUtils.isEmpty(formalType)) {
            example.and().andIn("formalType", formalType);
        }
        if (!CollectionUtils.isEmpty(postType)) {
            example.and().andIn("postType", postType);
        }
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoVO> selectByPhoneNameIdCard(String phoneNameIdCard, TokenUser tokenUser) {

        List<EmpInfoVO> empInfoVOList = selectPageByPhoneNameIdCard(phoneNameIdCard, 1, 10, tokenUser).getEntities();
        // 放入公司名称
        if (CollectionUtils.isEmpty(empInfoVOList)) {
            return new ArrayList<>();
        }
        return empInfoVOList;
    }

    @Override
    public Page<EmpInfoVO> selectPageByPhoneNameIdCard(String phoneNameIdCard, int pageNo, int pageSize, TokenUser tokenUser) {
        // 查询站点下的公司
        List<CompanyDO> companyDOList = companyService.selectBySiteId(tokenUser.getSiteId());
        if (CollectionUtils.isEmpty(companyDOList)) {
            // 没有公司肯定没员工
            return new Page<>(pageSize, pageNo);
        }
        // 公司id-name
        Map<String, String> idNameMap = companyDOList.parallelStream().collect(Collectors.toMap(BaseDO::getId, CompanyDO::getName, (v1, v2) -> v1));
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andIn("companyId", companyDOList.parallelStream().map(BaseDO::getId).collect(Collectors.toList()))
                .andIn("status", Arrays.asList(2, 3));
        example.and()
                .orLike("phone", "%" + phoneNameIdCard + "%")
                .orLike("name", "%" + phoneNameIdCard + "%")
                .orLike("idCard", "%" + phoneNameIdCard + "%");
        example.orderBy("gmtCreate");

        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, pageNo, pageSize);

        List<EmpInfoVO> empInfoVOList = empInfoDOPage.getEntities().parallelStream().map(empInfoDO -> {
            EmpInfoVO empInfoVO = empInfoDO.to(EmpInfoVO.class);
            empInfoVO.setCompanyName(idNameMap.get(empInfoVO.getCompanyId()));
            return empInfoVO;
        }).collect(Collectors.toList());
        return new Page<>(empInfoVOList, empInfoDOPage.getPageNo(), empInfoDOPage.getPageSize(), empInfoDOPage.getEntityCount());
    }

    @Override
    public List<EmpInfoDO> selectByPhonesAndSiteId(List<String> phones, String siteId) {

        if (CollectionUtils.isEmpty(phones)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true)
                .andIn("phone", phones);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectSiteEmp(TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByCompanyIdAndStatus(List<String> companyIdList, Integer status, String siteId) {

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        if (status != null) {
            example.and().andEqualTo("status", status);
        }
        if (CollectionKit.isNotEmpty(companyIdList)) {
            example.and().andIn("companyId", companyIdList);
        }
        example.orderBy("gmtCreate");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectAllByCompanyIds(List<String> companyIds, String siteId) {
        if (CollectionKit.isEmpty(companyIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true)
                .andIn("companyId", companyIds);
        example.orderBy("gmtCreate");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByPhonesAndCompanyId(List<String> phones, String companyId, String siteId) {
        if (CollectionUtils.isEmpty(phones)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andIn("phone", phones);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Page<EmpInfoDO> selectPageByPostType(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andNotEqualTo("status", 1)
                .andEqualTo("companyId", empInfoQuery.getCompanyId())
                .andEqualTo("postType", empInfoQuery.getPostType());
        if (!StringUtils.isEmpty(empInfoQuery.getNameOrPhone())) {
            example.and().andLike("name", "%" + empInfoQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + empInfoQuery.getNameOrPhone() + "%");
        }
        return empInfoDAO.selectPageByExample(example, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
    }

    @Override
    public EmpInfoDO selectByPhoneAndName(String phone, String name, String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("name", name)
                .andEqualTo("phone", phone)
                .andNotEqualTo("status", HAS_QUIT.getValue())
                .andEqualTo("companyId", companyId);
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExampleAndRowBounds(example, new RowBounds(0, 1));
        if (CollectionUtils.isEmpty(empInfoList)) {
            return null;
        }
        return empInfoList.get(0);
    }

    @Override
    public EmpInfoDO selectIdCardAndPhone(String idCard, String name, String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("name", name)
                .andEqualTo("idCard", idCard)
                .andEqualTo("companyId", companyId);
        List<EmpInfoDO> empInfoList = empInfoDAO.selectByExampleAndRowBounds(example, new RowBounds(0, 1));
        if (CollectionUtils.isEmpty(empInfoList)) {
            return null;
        }
        return empInfoList.get(0);
    }

    @Override
    public List<EmpInfoVO> selectByCompanyId(String companyId, String nameOrPhone, Boolean filter, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId);
        if (!ObjectUtils.isEmpty(filter) && filter) {
            example.and().andIn("status", Arrays.asList(HAS_ENTRY.getValue(), EmpInfoStatus.WAIT_QUIT.getValue()));
        }
        if (StrKit.isNotEmpty(nameOrPhone)) {
            example.and()
                    .orLike("name", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOS = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOS)) {
            return new ArrayList<>();
        }
        return empInfoDOS.stream().map(s -> {
            EmpInfoVO toResult = s.to(EmpInfoVO.class);
            Integer gender = toResult.getGender();
            if (!ObjectUtils.isEmpty(gender)) {
                toResult.setSex(gender == 1 ? "男" : "女");
            }
            return toResult;
        }).collect(Collectors.toList());
    }

    @Override
    public List<EmpInfoVO> selectByCompanyIds(List<String> companyIds, int yearly, int monthly
            , Integer empStatus, String nameOrPhoneOrIdCard, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(companyIds)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andIn("companyId", companyIds);
        if (StrKit.isNotEmpty(nameOrPhoneOrIdCard)) {
            example.and()
                    .orLike("name", "%" + nameOrPhoneOrIdCard + "%")
                    .orLike("phone", "%" + nameOrPhoneOrIdCard + "%")
                    .orLike("idCard", "%" + nameOrPhoneOrIdCard + "%");
        }
        if (empStatus != null) {
            example.and().andEqualTo("status", empStatus);
        } else {
            // 当月第一天
            Calendar calendar = Calendar.getInstance();
            // 年
            calendar.set(Calendar.YEAR, yearly);
            // 月
            calendar.set(Calendar.MONTH, monthly - 1);
            // 时
            calendar.set(Calendar.HOUR_OF_DAY, 0);
            // 分
            calendar.set(Calendar.MINUTE, 0);
            // 秒
            calendar.set(Calendar.SECOND, 0);
            // 毫秒
            calendar.set(Calendar.MILLISECOND, 0);
            Date firstTime = calendar.getTime();
            Date firstDayOfMonth = DateKit8.getFirstDayOfMonth(firstTime);
            example.and()
                    .orEqualTo("status", HAS_ENTRY.getValue())
                    .orEqualTo("status", WAIT_QUIT.getValue())
                    .orEqualTo("status", HAS_QUIT.getValue())
                    .andGreaterThanOrEqualTo("leaveDate", firstDayOfMonth);
        }
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOS = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOS)) {
            return new ArrayList<>();
        }
        return empInfoDOS.stream().map(s -> s.to(EmpInfoVO.class)).collect(Collectors.toList());
    }

    @Override
    public Page<EmpInfoVO> pageByCompanyId(SalaryCalculateRuleEmpInfoQuery salaryCalculateRuleEmpInfoQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", salaryCalculateRuleEmpInfoQuery.getCompanyId())
                .andEqualTo("salaryType", SalaryFileTypeEnum.WORK_SALARY.getValue());
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getNameOrPhone())) {
            example.and()
                    .orLike("name", "%" + salaryCalculateRuleEmpInfoQuery.getNameOrPhone() + "%")
                    .orLike("idCard", "%" + salaryCalculateRuleEmpInfoQuery.getNameOrPhone() + "%")
                    .orLike("phone", "%" + salaryCalculateRuleEmpInfoQuery.getNameOrPhone() + "%");
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getTag())) {
            List<String> tagList = ListKit.stringToList(salaryCalculateRuleEmpInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getPostType())) {
            example.and().andEqualTo("postType", salaryCalculateRuleEmpInfoQuery.getPostType());
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getEmpId())) {
            example.and().andEqualTo("id", salaryCalculateRuleEmpInfoQuery.getEmpId());
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getChannelId())) {
            example.and().andEqualTo("channelId", salaryCalculateRuleEmpInfoQuery.getChannelId());
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getStatus())) {
            example.and().andEqualTo("status", salaryCalculateRuleEmpInfoQuery.getStatus());
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getSalaryRuleId())) {
            example.and().andEqualTo("salaryRuleId", salaryCalculateRuleEmpInfoQuery.getSalaryRuleId());
        }
        if (StrKit.isNotEmpty(salaryCalculateRuleEmpInfoQuery.getServiceFeeRuleId())) {
            example.and().andEqualTo("serviceFeeRuleId", salaryCalculateRuleEmpInfoQuery.getServiceFeeRuleId());
        }
        example.orderBy("status").asc().orderBy("gmtCreate").desc();
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, salaryCalculateRuleEmpInfoQuery.getPageNo(), salaryCalculateRuleEmpInfoQuery.getPageSize());
        return empInfoDOPage.to(EmpInfoVO.class);
    }

    @Override
    public Page<EmpInfoVO> pageByCompanyId(String empId, String companyId, String nameOrPhone, Integer status,
                                           String channelId, String tag, Integer pageNo, Integer pageSize, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andEqualTo("salaryType", SalaryFileTypeEnum.WORK_SALARY.getValue());
        if (StrKit.isNotEmpty(nameOrPhone)) {
            example.and()
                    .orLike("name", "%" + nameOrPhone + "%")
                    .orLike("idCard", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }
        if (StrKit.isNotEmpty(tag)) {
            List<String> tagList = ListKit.stringToList(tag);
            findInSet(example, tagList, SQL_TAG);
        }
        if (StrKit.isNotEmpty(empId)) {
            example.and().andEqualTo("id", empId);
        }
        if (StrKit.isNotEmpty(channelId)) {
            example.and().andEqualTo("channelId", channelId);
        }
        if (StrKit.isNotEmpty(status)) {
            example.and().andEqualTo("status", status);
        }
        example.orderBy("status").asc().orderBy("gmtCreate").desc();
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, pageNo, pageSize);
        return empInfoDOPage.to(EmpInfoVO.class);
    }

    @Override
    public List<EmpInfoDO> listByCompanyId(String empId, String companyId, String nameOrPhone, Integer status,
                                           String channelId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andEqualTo("salaryType", SalaryFileTypeEnum.WORK_SALARY.getValue());
        if (StrKit.isNotEmpty(nameOrPhone)) {
            example.and()
                    .orLike("name", "%" + nameOrPhone + "%")
                    .orLike("idCard", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }
        if (StrKit.isNotEmpty(empId)) {
            example.and().andEqualTo("id", empId);
        }
        if (StrKit.isNotEmpty(channelId)) {
            example.and().andEqualTo("channelId", channelId);
        }
        if (StrKit.isNotEmpty(status)) {
            example.and().andEqualTo("status", status);
        }
        example.orderBy("status").asc().orderBy("gmtCreate").desc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Integer updateSalaryRule(SalaryRuleDTO salaryRuleDTO, TokenUser tokenUser) {
        EmpInfoDO empInfoDO = new EmpInfoDO();
        empInfoDO.setId(salaryRuleDTO.getEmpId());
        empInfoDO.setSalaryRuleId(salaryRuleDTO.getSalaryRuleId());
        empInfoDO.setServiceFeeRuleId(salaryRuleDTO.getServiceFeeRuleId());
        empInfoDO.setSalaryType(SalaryFileTypeEnum.WORK_SALARY.getValue());
        return this.empInfoDAO.updateByPrimaryKeySelective(empInfoDO);
    }

    @Override
    public List<EmpInfoDO> selectAllByCompanyId(String companyId, String nameOrPhoneOrIdCard, String employType,
                                                String postType, String formalType, Integer status, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true)
                .andEqualTo("companyId", companyId)
                .andEqualTo("salaryType", SalaryFileTypeEnum.FIX_SALARY.getValue());
        if (StrKit.isNotEmpty(nameOrPhoneOrIdCard)) {
            nameOrPhoneOrIdCard = "%" + nameOrPhoneOrIdCard + "%";
            example.and()
                    .andLike("name", nameOrPhoneOrIdCard)
                    .orLike("phone", nameOrPhoneOrIdCard)
                    .orLike("idCard", nameOrPhoneOrIdCard);
        }
        if (StrKit.isNotEmpty(employType)) {
            example.and().andEqualTo("employType", employType);
        }
        if (StrKit.isNotEmpty(postType)) {
            example.and().andEqualTo("postType", postType);
        }
        if (StrKit.isNotEmpty(formalType)) {
            example.and().andEqualTo("formalType", formalType);
        }
        if (Objects.nonNull(status)) {
            example.and().andEqualTo("status", status);
        }
        example.orderBy("gmtCreate").desc();
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Boolean isFixedEmp(String empId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("id", empId);
        example.selectProperties("postType", "phone");
        EmpInfoDO empInfoDO = empInfoDAO.selectOneByExample(example);
        log.info("查询员工信息，员工Id:{}，站点Id：{}", empId, tokenUser.getSiteId());
        ParamException.notNull(empInfoDO, "未查询到员工信息，请刷新后重试");
        // 先查外包 非外包直接返回
        return !empInfoDO.getPostType().equals(PostType.OUTSOURCE.getValue());
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public void updatePhoneByVoucher(UpdateByPhoneDTO updateByPhoneDTO, TokenUser tokenUser) {
        String voucher = updateByPhoneDTO.getVoucher();
        String oldPhone = updateByPhoneDTO.getOldPhone();
        String newPhone = updateByPhoneDTO.getPhone();
        String code = updateByPhoneDTO.getCode();
        ParamException.notNull(oldPhone, "旧手机号不能为空");
        // 凭证校验
        String phone = cache.get(org.jsola.user.common.CacheKeyKit.getUserVoucherKey(voucher));
        ParamException.notNull(phone, "请先获取凭证");
        UserDO userDO = userProviderService.selectUserById(tokenUser.getUserId());
        ParamException.isTrue(oldPhone.equals(userDO.getPhone()), "手机号码校验生成的凭证错误,请重新校验手机号");
        Boolean isSuccess = userProviderService.checkCodeWithUser(code, newPhone, "user_common_certification", tokenUser);
        ParamException.isTrue(isSuccess, "验证码不正确");
        updatePhone(oldPhone, newPhone, tokenUser);
    }

    @Override
    public void updatePhone(String oldPhone, String newPhone, TokenUser tokenUser) {
        // 更换用户的手机号
        UserDO userDO = userProviderService.selectByPhone(oldPhone);
        ParamException.notNull(userDO, "手机号对应用户不存在，请刷新后再试");
        userProviderService.updateUserPhone(userDO.getId(), oldPhone, newPhone, tokenUser);

        // 修改员工的手机号 离职也修改
        List<EmpInfoDO> empInfoDOList = selectByPhoneNotSiteId(oldPhone);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return;
        }
        for (EmpInfoDO empInfoDO : empInfoDOList) {
            TokenUser selectUser = new TokenUser();
            selectUser.setUserId(tokenUser.getUserId());
            selectUser.setSiteId(empInfoDO.getSiteId());
            // 检查新手机号是否有存在的员工
            EmpInfoDO newEmpInfoDO = selectByPhone(newPhone, selectUser);
            if (newEmpInfoDO != null) {
                ParamException.isTrue(userDO.getId().equals(newEmpInfoDO.getUserId()), "新手机号已绑定员工，请删除后再试");
            }
            empInfoDO.setPhone(newPhone);
            updateByIdSelective(empInfoDO, empInfoDO.getSiteId(), tokenUser.getUserId());
        }
        // 更换手机号完成后 将用户踢下线
        String userBaseTokenKey = UserCacheKeyKit.getUserBaseTokenKey("*", userDO.getId());
        cache.delKeysLike(userBaseTokenKey);
        String userInfoKey = UserCacheKeyKit.getUserInfoKey(userDO.getId());
        cache.delKey(userInfoKey);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchNoArrival(String[] empIds, TokenUser tokenUser) {

        int count = 0;
        for (String empId : empIds) {
            EmpInfoDO empInfoDO = this.selectDOById(empId, tokenUser.getSiteId());
            ParamException.notNull(empInfoDO, "员工信息不正确或已删除");
            if (!empInfoDO.getStatus().equals(EmpInfoStatus.WAIT_ENTRY.getValue())) {
                throw new ParamException("员工已不是待入职状态,不需要未到岗");
            }
            if (!empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                    && !empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_DISABLE.getValue())) {
                throw new ParamException("员工入职审批不通过,不能确认未到岗");
            }
            EmpInfoDO empInfoDOUpdate = new EmpInfoDO();
            empInfoDOUpdate.setId(empId);
            empInfoDOUpdate.setArrival(false);
            // 员工变动状态（0：当前无变动，1：转正中，2：调岗中，3： 离职中）
            empInfoDOUpdate.setChangeStatus(0);
            empInfoDOUpdate.preUpdate(tokenUser.getUserId());
            empInfoDOUpdate.setSiteId(tokenUser.getSiteId());
            count += empInfoDAO.updateByPrimaryKeySelective(empInfoDOUpdate);

            //如果有预登记记录，预登记状态也修改
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
            if (checkInPeopleDO != null) {
                CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                checkInPeopleUpdateDTO.setStatus(CheckInPeopleConstant.STATUS_NOT_ON_DUTY);
                checkInPeopleService.updateByIdSelective(checkInPeopleUpdateDTO.to(CheckInPeopleDO.class), tokenUser.getSiteId(), tokenUser.getUserId());
            }
        }
        return count;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchConfirmToJoin(List<EmpInfoUpdateDTO> empInfoUpdateDTOList, TokenUser tokenUser) {
        int count = 0;
        for (EmpInfoUpdateDTO empInfoUpdateDTO : empInfoUpdateDTOList) {
            EmpInfoDO empInfoDO = this.selectDOById(empInfoUpdateDTO.getId(), tokenUser.getSiteId());
            if (Objects.isNull(empInfoDO)) {
                throw new ParamException("员工信息不正确或已删除");
            } else if (!empInfoDO.getStatus().equals(EmpInfoStatus.WAIT_ENTRY.getValue())) {
                throw new ParamException("员工已不是待入职状态,不需要确认到岗");
            } else if (!empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                    && !empInfoDO.getApprovalStatus().equals(ApprovalStatusEnum.APPRO_DISABLE.getValue())) {
                throw new ParamException("员工入职审批不通过,不能确认到岗");
            }

            if (empInfoUpdateDTO.getPostType() == null) {
                empInfoUpdateDTO.setPostType(PostType.OTHER.getValue());
            }

            if (empInfoUpdateDTO.getJoinDate() == null) {
                throw new ParamException("【" + empInfoDO.getName() + "】请填写正确的员工入职时间");
            }

            this.confirmToJoin(empInfoUpdateDTO, tokenUser);
            count++;

            //预登记人员状态修改
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
            if (checkInPeopleDO != null) {
                CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                checkInPeopleUpdateDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
                checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
            }
            try {
                OperationEmpRecordAddDTO operationEmpRecordAddDTO = new OperationEmpRecordAddDTO();
                operationEmpRecordAddDTO.setEmpId(empInfoDO.getId());
                operationEmpRecordAddDTO.setEmpStatus(3);
                operationEmpRecordAddDTO.setQueryType(2);
                operationEmpRecordAddDTO.setInputUserId(tokenUser.getUserId());
                operationEmpRecordAddDTO.setUserId(empInfoDO.getUserId());
                operationEmpRecordAddDTO.setSourceTypeInfo("待入职转入职");
                operationEmpRecordAddDTO.setCompanyId(empInfoDO.getCompanyId());
                operationEmpRecordAddDTO.setMethodPath("org.jsola.hr.web.EmpInfoController.saveEmpInfoAndRule");
                operationEmpRecordService.save(operationEmpRecordAddDTO, tokenUser);
            } catch (Exception e) {
                log.error("员工记录异常");
            }
        }

        return count;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer onJobAgain(String empId, String flowId, TokenUser tokenUser) {
        String siteId = tokenUser.getSiteId();
        int count = 0;

        EmpInfoDO empInfoDO = selectDOById(empId, siteId);
        if (StrKit.isEmpty(flowId)) {
            empInfoDO.setArrival(null);
            empInfoDO.setApprovalStatus(ApprovalStatusEnum.APPRO_DISABLE.getValue());
            empInfoDO.preUpdate(tokenUser.getUserId());
            //重新入职发送通知
            sendNotice(empInfoDO, tokenUser);
            count = empInfoDAO.updateByPrimaryKey(empInfoDO);
        } else {
            // 待入职并且有审批模板的才发起审批
            if (!WAIT_ENTRY.getValue().equals(empInfoDO.getStatus())) {
                throw new ParamException("员工状态不是待入职");
            }
            String approCompanyId = empInfoDO.getCompanyId();

            NewApproDTO newApproDTO = new NewApproDTO();
            // 这里可以放置一些自定义的数据，前端在绘制审批明细时使用。假如这里放置是账单对象
            newApproDTO.setProps(JsonKit.toJSONString(empInfoDO));
            // 审批的标题
            newApproDTO.setTitle(empInfoDO.getName() + "的待入职审批");
            // 审批关联的业务类型，约定账单的subjectType是costBill
            newApproDTO.setSubjectType(HrConstants.SUBJECT_TYPE_HR_ON_JOB);
            // 审批关联的业务id，账单id，可以利用这个到时可以根据账单id查询该账单的所有审批历史
            newApproDTO.setSubjectId(empInfoDO.getId());
            // 设置审批的流程id，costBillAppro是超级后台设置的账单审批类型的code
            if (!approProviderService.checkFlowId(HrConstants.APPROVE_ON_JOB, approCompanyId, flowId, tokenUser)) {
                throw new ParamException("审批流程错误,请联系管理员");
            }
            newApproDTO.setFlowId(flowId);
            // costBillDO的所有属性会匹配审批表单里的字段，匹配到了就会设置在审批表单里
            newApproDTO.setPojo(empInfoDO);
            // 发起审批
            UserApproVO userApproVO = approProviderService.addUserAppro(newApproDTO, tokenUser);
            empInfoDO.setApprovalStatus(ApprovalStatusEnum.APPRO_ING.getValue());
            empInfoDO.setArrival(null);
            empInfoDO.preUpdate(tokenUser.getUserId());
            count = empInfoDAO.updateByPrimaryKey(empInfoDO);
        }

        try {
            //如果预登记有数据，状态需要改为待入职
            CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
            if (checkInPeopleDO != null) {
                CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
                checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
                checkInPeopleUpdateDTO.setStatus(CheckInPeopleConstant.STATUS_TO_BE_EMPLOYED);
                checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
            }
        } catch (Exception e) {
            throw new HrException("预登记修改状态失败");
        }
        return count;
    }

    @Override
    public List<EmpInfoDO> selectByTags(String companyId, String siteId, List<String> tagNameList) {
        List<EmpInfoDO> empInfoDOListAll = new ArrayList<>();

        for (String tagName : tagNameList) {
            Example example = new Example(EmpInfoDO.class);
            example.and()
                    .andEqualTo("valid", true)
                    .andEqualTo("siteId", siteId)
                    .andEqualTo("companyId", companyId)
                    .andCondition("FIND_IN_SET('" + tagName + "' , tag)");
            List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
            empInfoDOListAll.addAll(empInfoDOList);
        }
        return empInfoDOListAll;
    }

    @Override
    public EmpCountVO empCount(EmpCountQuery empCountQuery, TokenUser tokenUser) {
        String channelId = empCountQuery.getChannelId();
        String[] companyIds = empCountQuery.getCompanyIds();

        String siteId = tokenUser.getSiteId();
        Example example = new Example(EmpInfoDO.class);
        if (StrKit.isEmpty(channelId)) {
            example.and()
                    .andEqualTo("valid", true)
                    .andEqualTo("siteId", siteId);
        } else {
            example.and()
                    .andEqualTo("valid", true)
                    .andEqualTo("siteId", siteId)
                    .andEqualTo("channelId", channelId);
        }

        if (companyIds != null && companyIds.length > 0) {
            example.and().andIn("companyId", Arrays.asList(companyIds));
        }
        if (StrKit.isNotEmpty(empCountQuery.getNameOrPhone())) {
            String nameOrPhone = "%" + empCountQuery.getNameOrPhone() + "%";
            example.and()
                    .andLike("name", nameOrPhone)
                    .orLike("phone", nameOrPhone);
        }
        if (Objects.nonNull(empCountQuery.getStatus())) {
            Integer status = empCountQuery.getStatus();
            if (HAS_ENTRY.getValue().equals(status)) {
                example.and().andIn("status", Arrays.asList(HAS_ENTRY.getValue(), WAIT_QUIT.getValue()));
            } else {
                example.and().andEqualTo("status", status);
            }
        }
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        // 待入职员工
        List<EmpInfoDO> waitEntry = empInfoDOList.stream()
                .filter(s -> WAIT_ENTRY.getValue().equals(s.getStatus()))
                .collect(Collectors.toList());

        // 在职员工
        List<EmpInfoDO> hasEntry = empInfoDOList.stream()
                .filter(s -> WAIT_QUIT.getValue().equals(s.getStatus())
                        || HAS_ENTRY.getValue().equals(s.getStatus()))
                .collect(Collectors.toList());

        // 离职员工
        List<EmpInfoDO> hasQuit = empInfoDOList.stream()
                .filter(s -> HAS_QUIT.getValue().equals(s.getStatus()))
                .collect(Collectors.toList());
        Integer preRegistrationCount = checkInPeopleService.selectCountBySite(tokenUser, "花名册");
        EmpCountVO empCountVO = new EmpCountVO();
        empCountVO.setWaitEntryCount(waitEntry.size());
        empCountVO.setHasEntryCount(hasEntry.size());
        empCountVO.setHasQuitCount(hasQuit.size());
        empCountVO.setAllCount(empInfoDOList.size());
        empCountVO.setPreRegistrationCount(preRegistrationCount);
        return empCountVO;
    }

    @Override
    public MyEmpInfoVO selectByEmpId(String empId, TokenUser tokenUser) {
        String siteId = tokenUser.getSiteId();
        EmpInfoVO empInfoVO = selectById(empId, siteId);
        if (Objects.isNull(empInfoVO)) {
            return null;
        }
        MyEmpInfoVO myEmpInfoVO = empInfoVO.to(MyEmpInfoVO.class);
        CompanyVO companyVO = companyService.selectBaseCompanyById(myEmpInfoVO.getCompanyId(), siteId);
        if (Objects.nonNull(companyVO)) {
            myEmpInfoVO.setCompanyName(companyVO.getName());
        }
        String salaryRuleId = myEmpInfoVO.getSalaryRuleId();
        String serviceRuleId = myEmpInfoVO.getServiceFeeRuleId();
        // 工价规则
        if (StrKit.isNotEmpty(salaryRuleId)) {
            // 工价规则组，一个组下有多条规则
            SalaryCalculateRuleGroupVO ruleGroupVO = salaryCalculateRuleGroupService.selectById(salaryRuleId, siteId);
            if (Objects.nonNull(ruleGroupVO)) {
                // 工价规则明细
                List<SalaryCalculateRuleDO> ruleDOList = salaryCalculateRuleService.selectByGroupId(salaryRuleId, tokenUser);
                if (!CollectionUtils.isEmpty(ruleDOList)) {
                    List<SalaryCalculateRuleListVO> list = new ArrayList<>();
                    // 处理展示字段
                    for (SalaryCalculateRuleDO salaryCalculateRuleDO : ruleDOList) {
                        SalaryCalculateRuleListVO ruleListVO = salaryCalculateRuleDO.to(SalaryCalculateRuleListVO.class);
                        salaryCalculateRuleService.setReturnValueByListVO(ruleListVO);
                        list.add(ruleListVO);
                    }
                    ruleGroupVO.setSalaryRuleList(list);
                    myEmpInfoVO.setSalaryRuleGroupVO(ruleGroupVO);
                }
            }
        }
        // 劳务费规则
        if (StrKit.isNotEmpty(serviceRuleId)) {
            // 劳务费规则组，一个组下有多条规则
            SalaryCalculateRuleGroupVO ruleGroupVO = salaryCalculateRuleGroupService.selectById(serviceRuleId, siteId);
            if (Objects.nonNull(ruleGroupVO)) {
                // 劳务费规则明细
                List<SalaryCalculateRuleDO> ruleDOList = salaryCalculateRuleService.selectByGroupId(serviceRuleId, tokenUser);
                if (!CollectionUtils.isEmpty(ruleDOList)) {
                    List<SalaryCalculateRuleListVO> list = new ArrayList<>();
                    // 处理展示字段
                    for (SalaryCalculateRuleDO salaryCalculateRuleDO : ruleDOList) {
                        SalaryCalculateRuleListVO ruleListVO = salaryCalculateRuleDO.to(SalaryCalculateRuleListVO.class);
                        salaryCalculateRuleService.setReturnValueByListVO(ruleListVO);
                        list.add(ruleListVO);
                    }
                    ruleGroupVO.setServiceRuleList(list);
                    myEmpInfoVO.setServiceRuleGroupVO(ruleGroupVO);
                }
            }
        }
        // 工时
        Calendar calendar = Calendar.getInstance();
        int yearly = calendar.get(Calendar.YEAR);
        int monthly = calendar.get(Calendar.MONTH) + 1;
        List<WorkTimeVO> lastMonthWorkTime = salaryProviderService.getLastMonthWorkTime(Collections.singletonList(empId), yearly, monthly,
                tokenUser);
        float workTime = 0F;
        float workDay = 0F;
        for (WorkTimeVO workTimeVO : lastMonthWorkTime) {
            workTime += workTimeVO.getWorkTime();
            workDay += workTimeVO.getWorkDay();
        }
        myEmpInfoVO.setWorkTime(workTime);
        myEmpInfoVO.setWorkDay(workDay);
        // 渠道
        String channelId = myEmpInfoVO.getChannelId();
        if (StrKit.isNotEmpty(channelId)) {
            ChannelVO channelVO = channelService.selectById(channelId, siteId);
            if (Objects.nonNull(channelVO)) {
                myEmpInfoVO.setChannelVO(channelVO);
            }
        }
        // 参保记录
        List<EmpSocInfoDO> empSocInfoDOList = empSocInfoService.getEmpSocInfoByEmpIdOrderByGmtCreate(empId,
                siteId, empInfoVO.getCompanyId());
        List<EmpSocInfoVO> empSocInfoVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(empSocInfoDOList)) {
            empSocInfoVOList = empSocInfoDOList.stream()
                    .map(s -> {
                        EmpSocInfoVO result = s.to(EmpSocInfoVO.class);
                        result.setSort(Integer.parseInt(result.getYear() + result.getMonth()));
                        return result;
                    }).sorted(Comparator.comparing(EmpSocInfoVO::getSort))
                    .collect(Collectors.toList());
        }
        // 写入参保记录方案名称
        for (EmpSocInfoVO empSocInfoVO : empSocInfoVOList) {
            SocProgVO socProgVO = socProgService.selectById(empSocInfoVO.getProgId(), siteId);
            if (socProgVO != null) {
                empSocInfoVO.setSocProgName(socProgVO.getProgName());
            }
            List<Integer> statusList = Arrays.asList(empSocInfoVO.getEmpSocStatus(),
                    empSocInfoVO.getEmpMeStatus(), empSocInfoVO.getEmpPfStatus());
            if (statusList.contains(INCREMENT.getValue())) {
                empSocInfoVO.setEmpSocStatus(INCREMENT.getValue());
            } else if (statusList.contains(ATTRITION.getValue())) {
                empSocInfoVO.setEmpSocStatus(ATTRITION.getValue());
            }
        }
        myEmpInfoVO.setEmpSocInfoVOList(empSocInfoVOList);
        EmpSocRelatedDO empSocRelatedDO = empSocRelatedService.selectByEmpId(empInfoVO.getId(), siteId);
        if (Objects.nonNull(empSocRelatedDO) && StrKit.isNotEmpty(empSocRelatedDO.getSchemeId())) {
            SocProgVO socProgVO = socProgService.selectById(empSocRelatedDO.getSchemeId(), siteId);
            myEmpInfoVO.setSocProgVO(socProgVO);
        }
        // 自定义字段 id为key
        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList = empAdditionalFieldsService
                .selectByEmpId(empId, tokenUser.getSiteId());
        myEmpInfoVO.setEmpAdditionalFieldsDOList(empAdditionalFieldsDOList);
        // 员工异动
        EmpChangesDO empChangesDO = empChangesService.selectResignByEmpId(empId, tokenUser.getSiteId());
        if (empChangesDO != null) {
            // 预计离职时间
            myEmpInfoVO.setPreQuitDate(empChangesDO.getPreQuitDate());
            // 离职时间
            myEmpInfoVO.setQuitDate(empChangesDO.getQuitDate());
            // 离职原因
            myEmpInfoVO.setQuitReason(empChangesDO.getQuitReason());
            // 离职备注
            myEmpInfoVO.setQuitRemarks(empChangesDO.getQuitRemarks());
        }
        // 家庭成员
        // 家庭成员，取创建时间最早的一条
        List<EmpFamilyDO> empFamilyList = familyService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empFamilyList)) {
            // 创建时间正序
            empFamilyList = empFamilyList.stream().sorted(Comparator.comparing(EmpFamilyDO::getGmtCreate))
                    .collect(Collectors.toList());
            EmpFamilyDO empFamilyDO = empFamilyList.get(0);
            myEmpInfoVO.setFamilyName(empFamilyDO.getName());
            myEmpInfoVO.setFamilyPhone(empFamilyDO.getPhone());
            myEmpInfoVO.setFamilyRelation(empFamilyDO.getRelation());
            myEmpInfoVO.setFamilyWorkUnit(empFamilyDO.getWorkUnit());
        }
        // 紧急联系人，取创建时间最早的一条
        List<EmpContactsDO> empContactList = contactsService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empContactList)) {
            empContactList = empContactList.stream().sorted(Comparator.comparing(EmpContactsDO::getGmtCreate))
                    .collect(Collectors.toList());
            EmpContactsDO empContactsDO = empContactList.get(0);
            myEmpInfoVO.setContactsName(empContactsDO.getName());
            myEmpInfoVO.setContactsPhone(empContactsDO.getPhone());
            myEmpInfoVO.setContactsRelation(empContactsDO.getRelation());
            myEmpInfoVO.setContactsAddress(empContactsDO.getAddress());
        }
        // 教育经历
        List<EmpEducationDO> empEducationDOList = empEducationService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empEducationDOList)) {
            empEducationDOList = empEducationDOList.stream().sorted(Comparator.comparing(EmpEducationDO::getGmtCreate))
                    .collect(Collectors.toList());
            EmpEducationDO empEducationDO = empEducationDOList.get(0);
            myEmpInfoVO.setEducation(empEducationDO.getEducation());
            myEmpInfoVO.setGraCollege(empEducationDO.getGraCollege());
            myEmpInfoVO.setMajor(empEducationDO.getMajor());
            myEmpInfoVO.setStartTime(empEducationDO.getStartTime());
            myEmpInfoVO.setEndTime(empEducationDO.getEndTime());
            myEmpInfoVO.setEduStartTime(empEducationDO.getStartTime());
            myEmpInfoVO.setEduEndTime(empEducationDO.getEndTime());
            myEmpInfoVO.setTeaMethods(empEducationDO.getTeaMethods());
            myEmpInfoVO.setGraCerNumber(empEducationDO.getGraCerNumber());
            myEmpInfoVO.setDegreeType(empEducationDO.getDegreeType());
            myEmpInfoVO.setDegreeName(empEducationDO.getDegreeName());
            myEmpInfoVO.setDegreeNumber(empEducationDO.getDegreeNumber());
            myEmpInfoVO.setEducationRemark(empEducationDO.getEducationRemark());
        }
        // 工作经历
        List<EmpWorkDO> empWorkDOList = empWorkService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empWorkDOList)) {
            empWorkDOList = empWorkDOList.stream().sorted(Comparator.comparing(EmpWorkDO::getGmtCreate))
                    .collect(Collectors.toList());
            EmpWorkDO empWorkDO = empWorkDOList.get(0);
            myEmpInfoVO.setCompany(empWorkDO.getCompany());
            myEmpInfoVO.setPosition(empWorkDO.getPosition());
            myEmpInfoVO.setWorkStartTime(empWorkDO.getStartTime());
            myEmpInfoVO.setWorkEndTime(empWorkDO.getEndTime());
            myEmpInfoVO.setWitName(empWorkDO.getWitName());
            myEmpInfoVO.setWitPhone(empWorkDO.getWitPhone());
            myEmpInfoVO.setLeaveReason(empWorkDO.getLeaveReason());
            myEmpInfoVO.setLeaveSalary(empWorkDO.getLeaveSalary());
            myEmpInfoVO.setWorkRemark(empWorkDO.getRemark());
        }
        // 培训经历
        List<EmpTrainDO> empTrainDOList = empTrainService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empTrainDOList)) {
            empTrainDOList = empTrainDOList.stream().sorted(Comparator.comparing(EmpTrainDO::getGmtCreate))
                    .collect(Collectors.toList());
            EmpTrainDO empTrainDO = empTrainDOList.get(0);
            myEmpInfoVO.setTrainCourse(empTrainDO.getTrainCourse());
            myEmpInfoVO.setTrainOrgName(empTrainDO.getTrainOrgName());
            myEmpInfoVO.setTrainStartTime(empTrainDO.getStartTime());
            myEmpInfoVO.setTrainEndTime(empTrainDO.getEndTime());
            myEmpInfoVO.setAssessResult(empTrainDO.getAssessResult());
            myEmpInfoVO.setTrainCerName(empTrainDO.getTrainCerName());
            myEmpInfoVO.setTrainCerNumber(empTrainDO.getTrainCerNumber());
            myEmpInfoVO.setRemake(empTrainDO.getRemake());
        }
        // 奖惩记录
        List<EmpRewardPunishDO> empRewardPunishDOList =
                empRewardPunishService.listByEmpId(empId, tokenUser.getSiteId());
        if (!CollectionUtils.isEmpty(empRewardPunishDOList)) {
            empRewardPunishDOList = empRewardPunishDOList.stream()
                    .sorted(Comparator.comparing(EmpRewardPunishDO::getGmtCreate)).collect(Collectors.toList());
            EmpRewardPunishDO empRewardPunishDO = empRewardPunishDOList.get(0);
            myEmpInfoVO.setRewardPunish(empRewardPunishDO.getRewardPunish());
            myEmpInfoVO.setRewardType(empRewardPunishDO.getRewardType());
            myEmpInfoVO.setPunishType(empRewardPunishDO.getPunishType());
            myEmpInfoVO.setHandleDate(empRewardPunishDO.getHandleDate());
            myEmpInfoVO.setContent(empRewardPunishDO.getContent());
            myEmpInfoVO.setAmount(empRewardPunishDO.getAmount());
            myEmpInfoVO.setReason(empRewardPunishDO.getReason());
            myEmpInfoVO.setRewardsRemark(empRewardPunishDO.getRemark());
        }
        return myEmpInfoVO;
    }

    @Override
    public List<EmpInfoDO> selectEmpByCompanyId(String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId);
        example.selectProperties("id", "empSocStatus", "socProgId");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Page<EmpInfoVO> pageEmpListForMini(EmpCountQuery empCountQuery, TokenUser tokenUser) {
        PageInfo<EmpInfoDO> pageInfo = PageHelper.startPage(empCountQuery.getPageNo(), empCountQuery.getPageSize())
                .doSelectPageInfo(() -> empInfoDAO.pageEmpListForMini(empCountQuery, tokenUser.getSiteId()));
        Page<EmpInfoDO> resultPage = new Page<>(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), (int) pageInfo.getTotal());
        return resultPage.to(EmpInfoVO.class);
    }

    @Override
    public Page<EmpInfoVO> selectCurrentMonthByCompanyId(String companyId, String nameOrPhone
            , int yearly, int monthly, int pageNo, int pageSize, TokenUser tokenUser) {
        Example example = selectCurrentExample(companyId, nameOrPhone, yearly, monthly, tokenUser);
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, pageNo, pageSize);
        return empInfoDOPage.to(EmpInfoVO.class);
    }

    @Override
    public List<EmpInfoDO> selectCurrentMonthByCompanyId(String companyId, int yearly, int monthly, TokenUser tokenUser) {
        Example example = selectCurrentExample(companyId, null, yearly, monthly, tokenUser);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public Page<EmpInfoVO> pageNoFixSalaryFile(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andEqualTo("companyId", empInfoQuery.getCompanyId())
                .andEqualTo("salaryType", SalaryFileTypeEnum.NO_SALARY.getValue());
        if (StrKit.isNotEmpty(empInfoQuery.getNameOrPhone())) {
            String nameOrPhone = empInfoQuery.getNameOrPhone();
            nameOrPhone = "%" + nameOrPhone + "%";
            example.and()
                    .andLike("name", nameOrPhone)
                    .orLike("phone", nameOrPhone)
                    .orLike("idCard", nameOrPhone);
        }
        if (Objects.nonNull(empInfoQuery.getPostType())) {
            example.and().andEqualTo("postType", empInfoQuery.getPostType());
        }
        if (Objects.nonNull(empInfoQuery.getStatus())) {
            example.and().andEqualTo("status", empInfoQuery.getStatus());
        }
        if (StrKit.isNotEmpty(empInfoQuery.getChannelId())) {
            example.and().andEqualTo("channelId", empInfoQuery.getChannelId());
        }
        // 高级筛选(入职日期、标签)
        if (empInfoQuery.getJoinDateStart() != null && empInfoQuery.getJoinDateEnd() != null) {
            // 入职时间
            example.and().andBetween("joinDate", empInfoQuery.getJoinDateStart(), empInfoQuery.getJoinDateEnd());
        }
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            // 标签
            List<String> tags = ArrayKit.split(empInfoQuery.getTag(), ",");
            for (String tag : tags) {
                example.and().andCondition("FIND_IN_SET('" + tag + "' , tag)");
            }
        }
        example
                .orderBy("status").asc()
                .orderBy("gmtCreate").desc();
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
        Page<EmpInfoVO> empInfoVOPage = empInfoDOPage.to(EmpInfoVO.class);
        List<EmpInfoVO> empInfoVOList = empInfoVOPage.getEntities();
        if (CollectionUtils.isEmpty(empInfoVOList)) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
        List<String> empIdList = empInfoVOList.parallelStream()
                .map(EmpInfoVO::getId)
                .collect(Collectors.toList());
        List<ChannelVO> channelVOS = channelService.selectByEmpIds(empIdList, tokenUser.getSiteId());
        // 渠道id-渠道 Map
        Map<String, ChannelVO> idChannelVOMap = channelVOS.parallelStream()
                .collect(Collectors.toMap(ChannelVO::getId, Function.identity()));
        for (EmpInfoVO empInfoVO : empInfoVOList) {
            if (StrKit.isNotEmpty(empInfoVO.getChannelId())) {
                if (idChannelVOMap.containsKey(empInfoVO.getChannelId())) {
                    empInfoVO.setChannelVO(idChannelVOMap.get(empInfoVO.getChannelId()));
                }
            }
        }
        return empInfoVOPage;
    }

    @Override
    public EmpInfoPasteVO selectNoFixSalaryFileGroupByIdCards(String[] idCards, String companyId, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<String> idCardList = new ArrayList<>();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        for (String idCard : idCards) {
            Example example = new Example(EmpInfoDO.class);
            example.and()
                    .andEqualTo("idCard", idCard)
                    .andEqualTo("companyId", companyId)
                    .andEqualTo("salaryType", SalaryFileTypeEnum.NO_SALARY.getValue())
                    .andEqualTo("valid", true);
            List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
            if (!CollectionUtils.isEmpty(empInfoDOList)) {
                EmpInfoDO empInfoDO = empInfoDOList.get(0);
                if (empInfoVOList.removeIf(empInfoVO -> empInfoVO.getId().equals(empInfoDO.getId()))) {
                    idCardList.add(idCard);
                }
                empInfoVOList.add(empInfoDO.to(EmpInfoVO.class));
            } else {
                idCardList.add(idCard);
            }
        }
        empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public Page<EmpInfoVO> pageOutsource(String[] companyIds, String nameOrPhone, String channelId, Integer pageNo,
                                         Integer pageSize, String siteId) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId)
                .andEqualTo("postType", PostType.OUTSOURCE.getValue())
                .andIn("status", Arrays.asList(HAS_ENTRY.getValue(), WAIT_QUIT.getValue()));
        if (companyIds != null && companyIds.length != 0) {
            example.and().andIn("companyId", Arrays.asList(companyIds));
        }
        if (StrKit.isNotEmpty(channelId)) {
            example.and().andEqualTo("channelId", channelId);
        }
        if (StrKit.isNotEmpty(nameOrPhone)) {
            nameOrPhone = "%" + nameOrPhone + "%";
            example.and()
                    .andLike("name", nameOrPhone)
                    .orLike("phone", nameOrPhone);
        }
        example.orderBy("gmtCreate").desc();
        Page<EmpInfoDO> empInfoDOPage = empInfoDAO.selectPageByExample(example, pageNo, pageSize);
        return empInfoDOPage.to(EmpInfoVO.class);
    }

    private Example selectCurrentExample(String companyId, String nameOrPhone, int yearly, int monthly, TokenUser tokenUser) {
        // 当月第一天
        Calendar calendar = Calendar.getInstance();
        // 年
        calendar.set(Calendar.YEAR, yearly);
        // 月
        calendar.set(Calendar.MONTH, monthly - 1);
        // 时
        calendar.set(Calendar.HOUR_OF_DAY, 0);
        // 分
        calendar.set(Calendar.MINUTE, 0);
        // 秒
        calendar.set(Calendar.SECOND, 0);
        // 毫秒
        calendar.set(Calendar.MILLISECOND, 0);
        Date firstTime = calendar.getTime();
        Date firstDayOfMonth = DateKit8.getFirstDayOfMonth(firstTime);
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId);
        if (!StringUtils.isEmpty(nameOrPhone)) {
            example.and()
                    .orLike("name", "%" + nameOrPhone + "%")
                    .orLike("idCard", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", WAIT_QUIT.getValue())
                .orEqualTo("status", HAS_QUIT.getValue())
                .andGreaterThanOrEqualTo("leaveDate", firstDayOfMonth);
        example.orderBy("gmtCreate");

        example.selectProperties("id", "name", "phone", "status", "empPhoto", "idCard", "postType");
        return example;
    }

    @Override
    public List<EmpInfoDO> selectByPhoneNotSiteId(String phone) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("phone", phone);
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectOnJobByPhoneNotSiteId(String phone) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("phone", phone)
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue());
        return empInfoDAO.selectByExample(example);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer reinstatement(String companyId, String empId, TokenUser tokenUser) {
        // 查询已离职员工
        EmpInfoDO empInfoDO = selectResignedByCompanyIdAndEmpId(companyId, empId);
        HrException.notNull(empInfoDO, "没有需要恢复在职的员工");
        // 校验时候在其他公司入职
        checkByPhone(empInfoDO.getPhone(), empInfoDO.getSiteId(), tokenUser);
        // 更改员工状态
        empInfoDO.setStatus(2);
        empInfoDO.setLeaveDate(null);
        int updateByIdSelective = updateById(empInfoDO, empInfoDO.getSiteId(), tokenUser.getUserId());
        //预登记同步人员状态
        CheckInPeopleDO checkInPeopleDO = checkInPeopleService.selectByPhone(empInfoDO.getPhone(), tokenUser.getSiteId());
        if (checkInPeopleDO != null) {
            CheckInPeopleUpdateDTO checkInPeopleUpdateDTO = new CheckInPeopleUpdateDTO();
            checkInPeopleUpdateDTO.setId(checkInPeopleDO.getId());
            checkInPeopleUpdateDTO.setStatus(CheckInPeopleConstant.STATUS_RNTRY);
            checkInPeopleService.update(checkInPeopleUpdateDTO, tokenUser);
        }
        // 删除离职记录
        List<EmpChangesDO> empChangesDOList = empChangesService.selectLeaveByCompanyIdAndEmpId(companyId, empId);
        if (!CollectionUtils.isEmpty(empChangesDOList)) {
            String[] empChangesIds = empChangesDOList.parallelStream()
                    .map(EmpChangesDO::getId).toArray(String[]::new);
            empChangesService.deleteByIds(tokenUser, empChangesIds);
        }
//        // 恢复在职 恢复后台员工信息
//        userSiteService.recoverUser(empInfoDO.getUserId(), tokenUser);
        //发送人员变动通知
        sendNotice(empInfoDO, tokenUser);
        // 把这个员工的参保管理中的状态全部改为未离职
        empSocInfoService.updateWhetherLeave(Collections.singletonList(empId), false, null, tokenUser);
        return updateByIdSelective;
    }

    @Override
    public Integer reinstatement(String companyId, List<String> empIds, TokenUser tokenUser) {
        return null;
    }

    @Override
    public List<String> getEmpNameByIdList(List<String> empIdList) {
        List<EmpInfoDO> empInfoDOList = selectDoByIds(empIdList);
        return empInfoDOList.parallelStream().map(EmpInfoDO::getName).collect(Collectors.toList());
    }

    @Override
    public StatisticsPageVO selectHomeEmpCountByMonth(TokenUser tokenUser, String year, String month, List<String> companyIdList) {
        StatisticsPageVO statisticsPageVO = new StatisticsPageVO();
        // 把传进来的年月转换成Date类型,变成这个月的第一天
        Date beginDate = DateKit8.parse(year + "-" + month + "-01", "yyyy-MM-dd");
        // 拿到这个月的最后一天
        Date lastDayOfMonth = DateKit8.getEndTime(DateKit8.getLastDayOfMonth(beginDate));

        //查询这个站点下在这个时间之前的在职和待离职的员工
        Example working = new Example(EmpInfoDO.class);
        working.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andIn("status", Arrays.asList(2, 3))
                .andLessThan("gmtCreate", lastDayOfMonth);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            working.and().andIn("companyId", companyIdList);
        }
        int workingCount = empInfoDAO.selectCountByExample(working);
        statisticsPageVO.setWorkingCount(workingCount);
        // 这个月内离职的人数
        Example currentLeaving = new Example(EmpInfoDO.class);
        currentLeaving.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andBetween("leaveDate", beginDate, lastDayOfMonth);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            currentLeaving.and().andIn("companyId", companyIdList);
        }
        int currentLeavingCount = empInfoDAO.selectCountByExample(currentLeaving);
        statisticsPageVO.setCurrentLeavingCount(currentLeavingCount);
        // 这个月内在职的人数
        Example currentWorking = new Example(EmpInfoDO.class);
        currentWorking.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andBetween("joinDate", beginDate, lastDayOfMonth);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            currentWorking.and().andIn("companyId", companyIdList);
        }
        int currentWorkingCount = empInfoDAO.selectCountByExample(currentWorking);
        statisticsPageVO.setCurrentWorkingCount(currentWorkingCount);
        // 拿到上个月
        LocalDate dateTime = LocalDate.parse(year + "-" + month + "-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        String beforeYear = dateTime.minusMonths(1).getYear() + "";
        String beforeMonth = dateTime.minusMonths(1).format(DateTimeFormatter.ofPattern("yyyy-MM-dd")).substring(5, 7);
        // 拿到上个月的第一天
        Date beforeBeginDate = DateKit8.parse(beforeYear + "-" + beforeMonth + "-01", "yyyy-MM-dd");
        // 拿到上个月的最后一天
        Date beforeLastDayOfMonth = DateKit8.getEndTime(DateKit8.getLastDayOfMonth(beforeBeginDate));

        // 这上月内离职的人数
        Example beforeLeaving = new Example(EmpInfoDO.class);
        beforeLeaving.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andBetween("leaveDate", beforeBeginDate, beforeLastDayOfMonth);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            beforeLeaving.and().andIn("companyId", companyIdList);
        }
        int beforeLeavingCount = empInfoDAO.selectCountByExample(beforeLeaving);

        // 上个月内在职的人数
        Example beforeWorking = new Example(EmpInfoDO.class);
        beforeWorking.and()
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true)
                .andBetween("joinDate", beforeBeginDate, beforeLastDayOfMonth);
        if (!CollectionUtils.isEmpty(companyIdList)) {
            beforeWorking.and().andIn("companyId", companyIdList);
        }
        int beforeWorkingCount = empInfoDAO.selectCountByExample(beforeWorking);
        statisticsPageVO.setBeforeLeavingCount(currentLeavingCount - beforeLeavingCount);
        statisticsPageVO.setBeforeWorkingCount(currentWorkingCount - beforeWorkingCount);
        return statisticsPageVO;
    }

    @Override
    public EmpInfoDO selectEmpByNameAndIdCard(String empName, String idCard, String companyId, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("idCard", idCard)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("valid", true);
        if (!StringUtils.isEmpty(empName)) {
            example.and().andEqualTo("name", empName);
        }
        if (!StringUtils.isEmpty(companyId)) {
            example.and().andEqualTo("companyId", companyId);
        }
        example.selectProperties("id", "companyId");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        } else {
            return empInfoDOList.get(0);
        }
    }

    @Override
    public EmpInfoDO selectByPhone(String phone, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("phone", phone);
        // 按照创建时间倒序
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOList =
                empInfoDAO.selectByExampleAndRowBounds(example, new RowBounds(0, 1));
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public EmpInfoDO selectPropertyById(String id, TokenUser tokenUser, String... properties) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("id", id);
        example.selectProperties(properties);
        return empInfoDAO.selectOneByExample(example);
    }

    @Override
    public int selectCountByCompanyIdList(List<String> companyIdList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(companyIdList)) {
            return 0;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andIn("status", Arrays.asList(WAIT_QUIT.getValue(), HAS_ENTRY.getValue()))
                .andIn("companyId", companyIdList);
        return empInfoDAO.selectCountByExample(example);
    }

    @Override
    public int selectWaitEmpCountByCompanyIdList(List<String> companyIdList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(companyIdList)) {
            return 0;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", WAIT_ENTRY.getValue())
                .andIn("companyId", companyIdList);
        return empInfoDAO.selectCountByExample(example);
    }

    @Override
    public int selectLeaveEmpCountByCompanyIdList(List<String> companyIdList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(companyIdList)) {
            return 0;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_QUIT.getValue())
                .andIn("companyId", companyIdList);
        return empInfoDAO.selectCountByExample(example);
    }

    @Override
    public EmpInfoCheckVO selectResignedByPhoneAndIdCard(String companyId, String phone, String idCard, TokenUser tokenUser) {
        // 手机号/身份证号是否在员工表存在
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        example.and()
                .orEqualTo("phone", phone)
                .orEqualTo("idCard", idCard);
        example.setOrderByClause("FIELD(status,'2','3','1','4'), gmt_create desc");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            EmpInfoCheckVO empInfoCheckVO = new EmpInfoCheckVO();
            empInfoCheckVO.setHaveResigned(false);
            return empInfoCheckVO;
        }
        // 员工信息
        EmpInfoDO empInfoDO = null;
        // 原因
        String reason = "";
        boolean canAdd = true;
        // 手机号重复
        Map<String, EmpInfoDO> phoneEmpInfoDOMap = empInfoDOList.parallelStream()
                .collect(Collectors.toMap(EmpInfoDO::getPhone, v -> v, (v1, v2) -> v1));
        // 身份证号
        Map<String, EmpInfoDO> idCardEmpInfoDOMap = empInfoDOList.parallelStream()
                .collect(Collectors.toMap(EmpInfoDO::getIdCard, v -> v, (v1, v2) -> v1));
        if (phone != null) {
            empInfoDO = phoneEmpInfoDOMap.get(phone);
            if (empInfoDO != null) {
                reason = empInfoDO.getPhone() + "手机号存在于";
                canAdd = false;
            }
        }
        if (idCard != null && empInfoDO == null) {
            empInfoDO = idCardEmpInfoDOMap.get(idCard);
            if (empInfoDO != null) {
                reason = empInfoDO.getIdCard() + "身份证号存在于";
            }
        }
        if (empInfoDO == null) {
            return null;
        }
        CompanyVO companyVO = companyService.selectBaseCompanyById(empInfoDO.getCompanyId(), tokenUser.getSiteId());
        if (companyVO == null) {
            return null;
        }
        String companyName = companyVO.getName();
        EmpInfoCheckVO empInfoCheckVO = empInfoDO.to(EmpInfoCheckVO.class);
        empInfoCheckVO.setCompanyName(companyName);
        String empStatus;
        switch (empInfoDO.getStatus()) {
            case 1:
                empStatus = "待入职列表";
                break;
            case 2:
            case 3:
                empStatus = "在职列表";
                break;
            case 4:
                empStatus = "离职列表";
                break;
            default:
                empStatus = "状态有误";
        }
        ParamException.isFalse(companyId.equals(empInfoDO.getCompanyId()), reason + "本公司的" + empStatus);
        reason += companyName;
        empInfoCheckVO.setReason(reason + "的" + empStatus);
        empInfoCheckVO.setHaveResigned(true);
        // 分管公司是否拥有旧用工单位
        List<String> allCompanyList = new ArrayList<>();
        List<ChildCompanyListVO> childCompanyListVOList = childCompanyService.select(new ChildCompanyQuery(), tokenUser);
        // 公司权限
        boolean companyAuthority = false;
        for (ChildCompanyListVO childCompanyListVO : childCompanyListVOList) {
            if ("company".equals(childCompanyListVO.getType()) && empInfoDO.getCompanyId().equals(childCompanyListVO.getId())) {
                companyAuthority = true;
                break;
            } else if ("group".equals(childCompanyListVO.getType())) {
                List<ChildCompanyListVO> companyList = childCompanyListVO.getCompanyList();
                if (!CollectionUtils.isEmpty(companyList)) {
                    if (companyList.parallelStream().map(ChildCompanyListVO::getId).collect(Collectors.toList()).contains(empInfoDO.getCompanyId())) {
                        companyAuthority = true;
                        break;
                    }
                }
            } else if ("site".equals(childCompanyListVO.getType())) {
                companyAuthority = true;
                break;
            }
        }

        // 查看权限字符串 是否有花名册权限 (/hr/api/v1/permissions)
        // 菜单权限
        boolean menuAuthority;
        if (hrPermissionService.isAdmin(tokenUser.getUserId(), tokenUser.getSiteId())) {
            menuAuthority = true;
        } else {
            List<String> subjectTypeList = new ArrayList<>();
            subjectTypeList.add(SYSTEM_SUBJECT_TYPE);
            subjectTypeList.add(HR_SUBJECT_TYPE);
            subjectTypeList.add(COMPANY_SUBJECT_TYPE);
            List<MenuVO> menuList = adminProviderService.getMenuList(subjectTypeList);
            if (CollectionUtils.isEmpty(menuList)) {
                menuAuthority = false;
            } else {
                menuAuthority = menuList.parallelStream().map(MenuVO::getName).collect(Collectors.toList()).contains("花名册");
            }
        }
        empInfoCheckVO.setHaveAuthority(companyAuthority && menuAuthority);
        empInfoCheckVO.setCanAdd(canAdd || empInfoDO.getStatus() == 4);
        return empInfoCheckVO;
    }

    @Override
    public EmpInfoDO selectByUserIdAndCompanyId(String userId, String companyId) {
        if (StrKit.isEmpty(userId) || StrKit.isEmpty(companyId)) {
            return null;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("userId", userId)
                .andEqualTo("companyId", companyId);
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public EmpInfoDO selectByUserIdAndCompanyIdNotValid(String userId, String companyId) {
        if (StrKit.isEmpty(userId) || StrKit.isEmpty(companyId)) {
            return null;
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("userId", userId)
                .andEqualTo("companyId", companyId);
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return null;
        }
        return empInfoDOList.get(0);
    }

    @Override
    public Page<EmpInfoListVO> selectAllByEmpInfoQuery(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        String companyId = empInfoQuery.getCompanyId();
        ParamException.notNull(companyId, "用工单位Id不能为空");
        Example example = buildExample(empInfoQuery, tokenUser);
        example.orderBy("gmtCreate").desc();
        return tagPageList(empInfoQuery.getTag(), example, empInfoQuery.getPageNo(), empInfoQuery.getPageSize()).to(EmpInfoListVO.class);
    }

    @Override
    public CheckInEmpInfoListVO selectAllByCompanyIdAndIdCard(String companyId, List<String> cardList, TokenUser tokenUser) {

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        List<EmpInfoListVO> empInfoListVOList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(cardList)) {
            ParamException.notNull(companyId, "用工单位Id不能为空");
            Example example = new Example(EmpInfoDO.class);
            example.and()
                    .andEqualTo("valid", true)
                    .andEqualTo("companyId", companyId)
                    .andIn("idCard", cardList)
                    .andEqualTo("siteId", tokenUser.getSiteId());
            example.orderBy("gmtCreate").desc();
            List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
            if (!CollectionUtils.isEmpty(empInfoDOList)) {
                // 员工类型转预登记类型 于政要求
                empInfoListVOList = empInfoDOList.parallelStream().map(empInfoDO -> empInfoDO.to(EmpInfoListVO.class))
                        .parallel().collect(Collectors.toList());
                // 已查询到的身份证号 除去
                cardList.removeAll(empInfoDOList.parallelStream().map(EmpInfoDO::getIdCard)
                        .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
            }
        }
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOList);
        // 未查到的身份证号
        checkInEmpInfoListVO.setIdCardList(cardList);
        return checkInEmpInfoListVO;
    }


    @Override
    public boolean hasEmpResignByPhone(String companyId, String phone, TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位不能为空");
        ParamException.hasText(phone, "手机号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("phone", phone)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", HAS_QUIT.getValue());
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        return !CollectionUtils.isEmpty(empInfoDOList);
    }

    @Override
    public List<EmpInfoDO> listEmpResignByPhone(String companyId, List<String> phoneList, TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位不能为空");
        ParamException.notEmpty(phoneList, "手机号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("phone", phoneList)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", HAS_QUIT.getValue());
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public boolean hasEmpResignByIdCard(String companyId, String idCard, TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位不能为空");
        ParamException.hasText(idCard, "身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("idCard", idCard)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", HAS_QUIT.getValue());
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        return !CollectionUtils.isEmpty(empInfoDOList);
    }

    @Override
    public List<EmpInfoDO> listEmpResignByIdCard(String companyId, List<String> idCardList, TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位不能为空");
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andIn("idCard", idCardList)
                .andEqualTo("companyId", companyId)
                .andEqualTo("status", HAS_QUIT.getValue());
        return empInfoDAO.selectByExample(example);
    }

    private List<EmpInfoDO> selectImportEmpByIdCardList(String companyId, List<String> idCardList, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "员工身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);
        example.and()
                .orEqualTo("status", HAS_ENTRY.getValue())
                .orEqualTo("status", EmpInfoStatus.WAIT_QUIT.getValue());
        example.selectProperties("id", "idCard", "status", "formalType");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public CheckInEmpInfoListVO listPasteWaitJob(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", WAIT_ENTRY.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        // 设置员工状态
        parseWaitJoinApproveStatusList(empInfoListVOS, null);
        // 过滤去掉不是待入职的人
        empInfoListVOS.removeIf(s -> !PENDING_RELATION.equals(s.getApprovalAndStatus()));
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 已查询到的身份证号 除去
        idCardList.removeAll(empInfoListVOS.parallelStream().map(EmpInfoListVO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public CheckInEmpInfoListVO listPasteFormal(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");
        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_ENTRY.getValue())
                .andEqualTo("formalType", PROBATION.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class))
                .filter(s -> Objects.equals(s.getApprovalStatus(), ApprovalStatusEnum.APPRO_DISABLE.getValue()))
                .collect(Collectors.toList());
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 去除已查询到的身份证号
        idCardList.removeAll(empInfoListVOS.stream().map(EmpInfoListVO::getIdCard).collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public CheckInEmpInfoListVO listPasteOnJob(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_ENTRY.getValue())
                .andEqualTo("formalType", FORMAL.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList)
                .andIn("approvalStatus",
                        Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                                ApprovalStatusEnum.APPRO_DISABLE.getValue()));
        // 去除调岗的员
        example.and().andNotEqualTo("changeStatus", 2);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 已查询到的身份证号 除去
        idCardList.removeAll(empInfoDOList.parallelStream().map(EmpInfoDO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public CheckInEmpInfoListVO listPasteWaitLeave(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        // 查询员工
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", WAIT_QUIT.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList)
                .andIn("approvalStatus",
                        Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                                ApprovalStatusEnum.APPRO_DISABLE.getValue()));
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        // 查询离职变动记录
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        empChangesQuery.setChangeType(EmpChangeType.LEAVE.getValue());
        empChangesQuery.setCompanyId(companyId);
        List<EmpChangesListVO> empChangesListVOS = empChangesService.select(empChangesQuery, tokenUser.getSiteId());
        // 根据员工id分组，并保持顺序
        LinkedHashMap<String, List<EmpChangesListVO>> empIdChangesMap = empChangesListVOS.stream()
                .collect(Collectors.groupingBy(EmpChangesListVO::getEmpId, LinkedHashMap::new, Collectors.toList()));
        Iterator<EmpInfoListVO> iterator = empInfoListVOS.iterator();
        while (iterator.hasNext()) {
            EmpInfoListVO empInfoListVO = iterator.next();
            List<EmpChangesListVO> empChangesList = empIdChangesMap.get(empInfoListVO.getId());
            // 没有变动记录就过滤掉
            if (CollectionUtils.isEmpty(empChangesList)) {
                iterator.remove();
            }
            empInfoListVO.setEmpChangesListVO(empChangesList.get(0));
        }
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 已查询到的身份证号 除去
        idCardList.removeAll(empInfoDOList.parallelStream().map(EmpInfoDO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public CheckInEmpInfoListVO listPasteTransferRelation(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        // 查询员工
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_ENTRY.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList)
                // 员工调岗的记录
                .andEqualTo("changeStatus", 2)
                .andIn("approvalStatus",
                        Arrays.asList(ApprovalStatusEnum.APPRO_SUCCESS.getValue(),
                                ApprovalStatusEnum.APPRO_DISABLE.getValue()));

        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        // 查询调岗变动记录
        EmpChangesQuery empChangesQuery = new EmpChangesQuery();
        empChangesQuery.setChangeType(EmpChangeType.TRANSFER__POSITION.getValue());
        empChangesQuery.setCompanyId(companyId);
        List<EmpChangesListVO> empChangesListVOS = empChangesService.select(empChangesQuery, tokenUser.getSiteId());
        // 根据员工id分组，并保持顺序
        LinkedHashMap<String, List<EmpChangesListVO>> empIdChangesMap = empChangesListVOS.stream()
                .collect(Collectors.groupingBy(EmpChangesListVO::getEmpId, LinkedHashMap::new, Collectors.toList()));
        Iterator<EmpInfoListVO> iterator = empInfoListVOS.iterator();
        while (iterator.hasNext()) {
            EmpInfoListVO empInfoListVO = iterator.next();
            List<EmpChangesListVO> empChangesList = empIdChangesMap.get(empInfoListVO.getId());
            // 没有变动记录就过滤掉
            if (CollectionUtils.isEmpty(empChangesList)) {
                iterator.remove();
            }
            empInfoListVO.setEmpChangesListVO(empChangesList.get(0));
        }
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 已查询到的身份证号 除去
        idCardList.removeAll(empInfoDOList.parallelStream().map(EmpInfoDO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchReinstatement(String companyId, String[] empIds, TokenUser tokenUser) {
        ParamException.notEmpty(empIds, "员工id不能为空");
        int count = 0;
        for (String empId : empIds) {
            count += reinstatement(companyId, empId, tokenUser);
        }
        return count;
    }


    @Override
    public Page<EmpInfoListVO> pageResignedList(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        List<EmpInfoListVO> empInfoListVOS = listLeaveRelation(empInfoQuery, tokenUser);
        empInfoListVOS = filterSocEmp(empInfoListVOS, tokenUser);
        return PageKit.startPage(empInfoListVOS, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
    }

    @Override
    public CheckInEmpInfoListVO listPasteResigned(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        // 查询员工
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_QUIT.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);

        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class)).collect(Collectors.toList());
        empInfoListVOS = filterSocEmp(empInfoListVOS, tokenUser);
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 已查询到的身份证号 除去
        idCardList.removeAll(empInfoListVOS.parallelStream().map(EmpInfoListVO::getIdCard)
                .filter(Objects::nonNull).distinct().collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public Page<EmpInfoListVO> pageReinstatementEmp(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        List<EmpInfoListVO> empInfoListVOS = listReinstatementEmp(empInfoQuery, tokenUser);
        return PageKit.startPage(empInfoListVOS, empInfoQuery.getPageNo(), empInfoQuery.getPageSize());
    }

    @Override
    public List<EmpInfoListVO> listReinstatementEmp(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {

        String companyId = empInfoQuery.getCompanyId();
        ParamException.hasText(companyId, "用工单位id不能为空");
        Example example = buildExample(empInfoQuery, tokenUser);
        example.and()
                .andEqualTo("status", HAS_QUIT.getValue());
        if (empInfoQuery.getTag() != null) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOS = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOS)) {
            return new ArrayList<>();
        }
        List<String> idCards = empInfoDOS.parallelStream().map(EmpInfoDO::getIdCard).collect(Collectors.toList());
        List<String> phones = empInfoDOS.parallelStream().map(EmpInfoDO::getPhone).collect(Collectors.toList());
        // 可以恢复在职的员工手机号
        List<String> phoneList = listPhoneListCanResumeWork(phones, companyId, tokenUser);
        // 可以恢复在职的员工身份证号
        List<String> idCardList = listIdCardListCanResumeWork(idCards, companyId, tokenUser);
        return empInfoDOS.stream()
                .filter(s -> phoneList.contains(s.getPhone()) && idCardList.contains(s.getIdCard()))
                .map(empInfoDO -> {
                    // 既在可以恢复在职的手机号中，又在可以恢复在职的身份证号中
                    if (phoneList.contains(empInfoDO.getPhone())
                            && idCardList.contains(empInfoDO.getIdCard())) {
                        return empInfoDO.to(EmpInfoListVO.class);
                    } else {
                        return null;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList());
    }

    @Override
    public List<String> listIdCardListCanResumeWork(List<String> idCards, String companyId, TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位id不能为空");

        // 身份证号都为空，返回空
        if (CollectionUtils.isEmpty(idCards)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("idCard", idCards)
                .andNotEqualTo("companyId", companyId)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("valid", true);
        example.selectProperties("id", "name", "companyId", "status", "phone", "idCard");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        // 如果查不出来，说明都没有在其他公司入职
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return idCards;
        }
        List<String> idCardList = empInfoDOList.parallelStream().map(EmpInfoDO::getIdCard).collect(Collectors.toList());
        idCards.removeAll(idCardList);
        return idCards;
    }

    @Override
    public List<String> listPhoneListCanResumeWork(List<String> phones, String companyId,
                                                   TokenUser tokenUser) {
        ParamException.hasText(companyId, "用工单位id不能为空");

        // 手机号为空，返回空
        if (CollectionUtils.isEmpty(phones)) {
            return new ArrayList<>();
        }
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andIn("phone", phones)
                .andNotEqualTo("companyId", companyId)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andNotEqualTo("status", EmpInfoStatus.HAS_QUIT.getValue())
                .andEqualTo("valid", true);
        example.selectProperties("id", "name", "companyId", "status", "phone", "idCard");
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        // 如果查不出来，说明都没有在其他公司入职
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            return phones;
        }
        List<String> phoneList = empInfoDOList.parallelStream().map(EmpInfoDO::getPhone).collect(Collectors.toList());
        phones.removeAll(phoneList);
        return phones;
    }

    @Override
    public CheckInEmpInfoListVO listPasteReinstatementEmp(List<String> idCardList, String companyId,
                                                          TokenUser tokenUser) {

        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");

        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList)
                .andEqualTo("status", HAS_QUIT.getValue());
        example.orderBy("gmtCreate").desc();
        List<EmpInfoDO> empInfoDOS = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOS)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<String> idCards = empInfoDOS.parallelStream().map(EmpInfoDO::getIdCard).collect(Collectors.toList());
        List<String> phones = empInfoDOS.parallelStream().map(EmpInfoDO::getPhone).collect(Collectors.toList());
        // 可以恢复在职的员工手机号
        List<String> phoneList = listPhoneListCanResumeWork(phones, companyId, tokenUser);
        // 可以恢复在职的员工身份证号
        List<String> idCardListOK = listIdCardListCanResumeWork(idCards, companyId, tokenUser);
        List<EmpInfoListVO> empInfoListVOS = empInfoDOS.stream()
                .filter(s -> phoneList.contains(s.getPhone()) && idCards.contains(s.getIdCard()))
                .map(empInfoDO -> {
                    // 既在可以恢复在职的手机号中，又在可以恢复在职的身份证号中
                    if (phoneList.contains(empInfoDO.getPhone())
                            && idCardListOK.contains(empInfoDO.getIdCard())) {
                        return empInfoDO.to(EmpInfoListVO.class);
                    } else {
                        return null;
                    }
                }).filter(Objects::nonNull).collect(Collectors.toList());
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        idCardList.removeAll(empInfoListVOS.parallelStream()
                .map(EmpInfoListVO::getIdCard).collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    @Override
    public Page<EmpInfoListVO> selectForLeave(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        empInfoQuery.setStatus(2);
        empInfoQuery.setEmployType(true);
        empInfoQuery.setFormalType(PROBATION.getValue());

        Example example = buildExample(empInfoQuery, tokenUser);
        example.and()
                .andEqualTo("approvalStatus", ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                .orEqualTo("approvalStatus", ApprovalStatusEnum.APPRO_DISABLE.getValue());
        if (StrKit.isNotEmpty(empInfoQuery.getTag())) {
            List<String> tagList = ArrayKit.split(empInfoQuery.getTag());
            findInSet(example, tagList, SQL_TAG);
        }
        Page<EmpInfoDO> page = empInfoDAO.selectPageByExample(example, empInfoQuery.getPageNo(),
                empInfoQuery.getPageSize());
        if (CollectionUtils.isEmpty(page.getEntities())) {
            return new Page<>(empInfoQuery.getPageSize(), empInfoQuery.getPageNo());
        }
        return page.to(EmpInfoListVO.class);
    }

    @Override
    public EmpInfoPasteVO selectEmpByCardAndSalaryType(EmpInfoQuery empInfoQuery, TokenUser tokenUser) {
        EmpInfoPasteVO empInfoPasteVO = new EmpInfoPasteVO();
        List<EmpInfoVO> empInfoVOList = new ArrayList<>();
        List<String> idCardList = empInfoQuery.getIdCardList();
        ParamException.notEmpty(empInfoQuery.getIdCardList(), "身份证号不能为空");
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("companyId", empInfoQuery.getCompanyId())
                .andEqualTo("salaryType", empInfoQuery.getSalaryType())
                .andIn("idCard", idCardList);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (!CollectionUtils.isEmpty(empInfoDOList)) {
            Map<String, EmpInfoDO> idCardEmp = empInfoDOList.stream().collect(Collectors.toMap(EmpInfoDO::getIdCard, p -> p));
            Iterator<String> iterator = idCardList.iterator();
            while (iterator.hasNext()) {
                String idCard = iterator.next();
                if (idCardEmp.containsKey(idCard)) {
                    empInfoVOList.add(idCardEmp.get(idCard).to(EmpInfoVO.class));
                    iterator.remove();
                }
            }
            empInfoPasteVO.setEmpInfoVOList(empInfoVOList);
        }
        empInfoPasteVO.setIdCardList(idCardList);
        return empInfoPasteVO;
    }

    @Override
    public CheckInEmpInfoListVO listPasteFormalForLeave(List<String> idCardList, String companyId, TokenUser tokenUser) {
        ParamException.notEmpty(idCardList, "身份证号不能为空");
        ParamException.hasText(companyId, "用工单位id不能为空");
        CheckInEmpInfoListVO checkInEmpInfoListVO = new CheckInEmpInfoListVO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId())
                .andEqualTo("status", HAS_ENTRY.getValue())
                .andEqualTo("formalType", PROBATION.getValue())
                .andEqualTo("companyId", companyId)
                .andIn("idCard", idCardList);
        List<EmpInfoDO> empInfoDOList = empInfoDAO.selectByExample(example);
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            checkInEmpInfoListVO.setIdCardList(idCardList);
            return checkInEmpInfoListVO;
        }
        List<EmpInfoListVO> empInfoListVOS = empInfoDOList.stream()
                .map(s -> s.to(EmpInfoListVO.class))
                .filter(s ->
                        // 只保留审批通过或者不需要审批的人
                        Objects.equals(s.getApprovalStatus(), ApprovalStatusEnum.APPRO_SUCCESS.getValue())
                                || Objects.equals(s.getApprovalStatus(), ApprovalStatusEnum.APPRO_DISABLE.getValue()
                        ))
                .collect(Collectors.toList());
        checkInEmpInfoListVO.setEmpInfoListVOList(empInfoListVOS);
        // 去除已查询到的身份证号
        idCardList.removeAll(empInfoListVOS.stream().map(EmpInfoListVO::getIdCard).collect(Collectors.toList()));
        checkInEmpInfoListVO.setIdCardList(idCardList);
        return checkInEmpInfoListVO;
    }

    /**
     * 过滤正在参保的人
     */
    private List<EmpInfoListVO> filterSocEmp(List<EmpInfoListVO> empInfoList, TokenUser tokenUser) {
        if (CollectionUtils.isEmpty(empInfoList)) {
            return new ArrayList<>();
        }
        List<String> empIdList = empInfoList.stream().map(EmpInfoListVO::getId).collect(Collectors.toList());
        List<EmpSocRelatedDO> empSocRelated = empSocRelatedService.selectByEmpIdList(empIdList, tokenUser.getSiteId());
        Map<String, EmpSocRelatedDO> empSocRelatedMap = empSocRelated.stream()
                .collect(Collectors.toMap(EmpSocRelatedDO::getEmpId, v -> v));
        // 过滤掉正在参保的人
        empInfoList = empInfoList.stream().filter(empInfo -> {
            EmpSocRelatedDO empSocRelatedDO = empSocRelatedMap.get(empInfo.getId());
            if (EmpSocStatus.INCREMENT.getValue().equals(empSocRelatedDO.getSocState()) ||
                    EmpSocStatus.NORMAL_SOC.getValue().equals(empSocRelatedDO.getSocState())) {
                return false;
            }
            if (EmpSocStatus.INCREMENT.getValue().equals(empSocRelatedDO.getMeState()) ||
                    EmpSocStatus.NORMAL_SOC.getValue().equals(empSocRelatedDO.getMeState())) {
                return false;
            }
            return !EmpSocStatus.INCREMENT.getValue().equals(empSocRelatedDO.getPfState()) &&
                    !EmpSocStatus.NORMAL_SOC.getValue().equals(empSocRelatedDO.getPfState());
        }).collect(Collectors.toList());
        return empInfoList;
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public Integer batchUpdateSalaryInfo(EmpInfoUpdateDTO empInfoUpdateDTO, TokenUser tokenUser) {
        ParamException.notEmpty(empInfoUpdateDTO.getEmpIdList(), "修改失败：未指定员工");
        if (empInfoUpdateDTO.getSalaryType() == 1) {
            //todo 校验是否是同一模板
        }
        for (String empId : empInfoUpdateDTO.getEmpIdList()) {
            empInfoUpdateDTO.setPhone(null);
            empInfoUpdateDTO.setId(empId);
            EmpInfoDO empInfoDO = empInfoUpdateDTO.to(EmpInfoDO.class);
            updateByIdSelective(empInfoDO, tokenUser.getSiteId(), tokenUser.getUserId());
        }
        return 1;
    }

    @Override
    public Long getEmpJoinDate(EmpListQuery empListQuery, TokenUser tokenUser) {
        Date lastDate = null;
        List<EmpInfoDO> empInfoDOList = selectDoByIds(empListQuery.getEmpIdList());
        if (CollectionUtils.isEmpty(empInfoDOList)) {
            throw new ParamException("未查到员工信息");
        }
        for (EmpInfoDO empInfoDO : empInfoDOList) {
            if (lastDate == null || empInfoDO.getJoinDate().after(lastDate)) {
                lastDate = empInfoDO.getJoinDate();
            }
        }
        return lastDate == null ? null : lastDate.getTime();
    }

    @Override
    public List<EmpInfoDO> selectByCompanyIdsAndStatusAndIdCard(List<String> companyIds, Integer status, String idCard, String siteId) {

        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", siteId)
                .andEqualTo("valid", true);
        if (CollectionKit.isNotEmpty(companyIds)) {
            example.and().andIn("companyId", companyIds);
        }
        if (status != null) {
            example.and().andEqualTo("status", status);
        }
        if (StrKit.isNotEmpty(idCard)) {
            example.and().andLike("idCard", "%" + idCard + "%");
        }
        example.orderBy("gmtCreate");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpInfoDO> selectByNameOrPhoneAndCompanyIdAndIdCard(String nameOrPhone, List<String> companyIdList, String idCard, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("siteId", tokenUser.getSiteId());
        if (CollectionKit.isNotEmpty(companyIdList)) {
            example.and().andIn("companyId", companyIdList);
        }
        if (StrKit.isNotEmpty(idCard)) {
            example.and().andLike("idCard", "%" + idCard + "%");
        }
        if (StrKit.isNotEmpty(nameOrPhone)) {
            example.and()
                    .orLike("name", "%" + nameOrPhone + "%")
                    .orLike("phone", "%" + nameOrPhone + "%");
        }
        example.orderBy("gmtCreate");
        return empInfoDAO.selectByExample(example);
    }

    @Override
    public List<EmpReduceInfoVO> selectEmpReduceInfoByIdList(List<String> empIdList) {
        return empInfoDAO.selectEmpReduceInfoByIdList(empIdList);
    }

    @Override
    @Transactional(value = HrConstants.TX, rollbackFor = Exception.class)
    public int insertListAndSetId(List<EmpInfoDO> empInfoList) {
        return empInfoDAO.insertListAndSetId(empInfoList);
    }

    @Override
    public List<EmpFieldDTO> getEmpFieldList(Integer queryType, String empId, String onboardingCompanyId, TokenUser tokenUser) {
        // 员工所有填写信息
        List<EmpFieldDTO> allFieldDTOList = new ArrayList<>();
        List<EmpFieldDTO> empFieldDTOList;
        // 自定义字段信息
        List<EmpAdditionalFieldsDO> empAdditionalFieldsDOList;
        // 员工类型 使用 CustomerModuleType
        String moduleCode;
        // 用工单位Id
        String companyId;
        // 花名册
        EmpInfoVO empInfoVO = selectById(empId, tokenUser.getSiteId());
        // 预登记
        CheckInPeopleVO checkInPeopleVO = checkInPeopleService.selectById(empId, tokenUser.getSiteId());

        //工作性质
        List<DictItemDO> postTypeList = adminProviderService.selectAllDictItem(null, POST_TYPE, tokenUser);
        Map<String, String> postTypeMap = postTypeList.stream().collect(Collectors.toMap(DictItemDO::getDictItemValue, DictItemDO::getDictItemKey, (key1, key2) -> key2));

        // 先查询是否为预登记
        if (empInfoVO != null) {
            ParamException.notNull(empInfoVO.getStatus(), "员工状态不正确，请联系管理员");
            if (queryType == 2) {
                if (empInfoVO.getStatus() == 1) {
                    moduleCode = CustomerModuleType.WAIT_JOB.getValue();
                } else if (empInfoVO.getStatus() == 2 || empInfoVO.getStatus() == 3 || empInfoVO.getStatus() == 4) {
                    moduleCode = CustomerModuleType.ON_JOB.getValue();
                } else {
                    throw new ParamException("员工状态不正确，请联系管理员");
                }
            } else if (queryType == 3) {
                moduleCode = CustomerModuleType.WAIT_JOB.getValue();
            } else if (queryType == 4) {
                moduleCode = CustomerModuleType.ON_JOB.getValue();
            } else {
                throw new ParamException("查询员工类型有误");
            }
            // 家庭成员，取创建时间最早的一条
            List<EmpFamilyDO> empFamilyList = familyService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empFamilyList)) {
                // 创建时间正序
                empFamilyList = empFamilyList.stream().sorted(Comparator.comparing(EmpFamilyDO::getGmtCreate))
                        .collect(Collectors.toList());
                EmpFamilyDO empFamilyDO = empFamilyList.get(0);
                empInfoVO.setFamilyName(empFamilyDO.getName());
                empInfoVO.setFamilyPhone(empFamilyDO.getPhone());
                empInfoVO.setFamilyRelation(empFamilyDO.getRelation());
                empInfoVO.setFamilyWorkUnit(empFamilyDO.getWorkUnit());
            }
            // 紧急联系人，取创建时间最早的一条
            List<EmpContactsDO> empContactList = contactsService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empContactList)) {
                empContactList = empContactList.stream().sorted(Comparator.comparing(EmpContactsDO::getGmtCreate))
                        .collect(Collectors.toList());
                EmpContactsDO empContactsDO = empContactList.get(0);
                empInfoVO.setContactsName(empContactsDO.getName());
                empInfoVO.setContactsPhone(empContactsDO.getPhone());
                empInfoVO.setContactsRelation(empContactsDO.getRelation());
                empInfoVO.setContactsAddress(empContactsDO.getAddress());
            }
            // 教育经历
            List<EmpEducationDO> empEducationDOList = empEducationService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empEducationDOList)) {
                empEducationDOList = empEducationDOList.stream().sorted(Comparator.comparing(EmpEducationDO::getGmtCreate))
                        .collect(Collectors.toList());
                EmpEducationDO empEducationDO = empEducationDOList.get(0);
                empInfoVO.setEducation(empEducationDO.getEducation());
                empInfoVO.setGraCollege(empEducationDO.getGraCollege());
                empInfoVO.setMajor(empEducationDO.getMajor());
                empInfoVO.setStartTime(empEducationDO.getStartTime());
                empInfoVO.setEndTime(empEducationDO.getEndTime());
                empInfoVO.setTeaMethods(empEducationDO.getTeaMethods());
                empInfoVO.setGraCerNumber(empEducationDO.getGraCerNumber());
                empInfoVO.setDegreeType(empEducationDO.getDegreeType());
                empInfoVO.setDegreeName(empEducationDO.getDegreeName());
                empInfoVO.setDegreeNumber(empEducationDO.getDegreeNumber());
                empInfoVO.setEducationRemark(empEducationDO.getEducationRemark());
            }
            // 工作经历
            List<EmpWorkDO> empWorkDOList = empWorkService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empWorkDOList)) {
                empWorkDOList = empWorkDOList.stream().sorted(Comparator.comparing(EmpWorkDO::getGmtCreate))
                        .collect(Collectors.toList());
                EmpWorkDO empWorkDO = empWorkDOList.get(0);
                empInfoVO.setCompany(empWorkDO.getCompany());
                empInfoVO.setPosition(empWorkDO.getPosition());
                empInfoVO.setWorkStartTime(empWorkDO.getStartTime());
                empInfoVO.setWorkEndTime(empWorkDO.getEndTime());
                empInfoVO.setWitName(empWorkDO.getWitName());
                empInfoVO.setWitPhone(empWorkDO.getWitPhone());
                empInfoVO.setLeaveReason(empWorkDO.getLeaveReason());
                empInfoVO.setLeaveSalary(empWorkDO.getLeaveSalary());
                empInfoVO.setWorkRemark(empWorkDO.getRemark());
            }
            // 培训经历
            List<EmpTrainDO> empTrainDOList = empTrainService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empTrainDOList)) {
                empTrainDOList = empTrainDOList.stream().sorted(Comparator.comparing(EmpTrainDO::getGmtCreate))
                        .collect(Collectors.toList());
                EmpTrainDO empTrainDO = empTrainDOList.get(0);
                empInfoVO.setTrainCourse(empTrainDO.getTrainCourse());
                empInfoVO.setTrainOrgName(empTrainDO.getTrainOrgName());
                empInfoVO.setTrainStartTime(empTrainDO.getStartTime());
                empInfoVO.setTrainEndTime(empTrainDO.getEndTime());
                empInfoVO.setAssessResult(empTrainDO.getAssessResult());
                empInfoVO.setTrainCerName(empTrainDO.getTrainCerName());
                empInfoVO.setTrainCerNumber(empTrainDO.getTrainCerNumber());
                empInfoVO.setRemake(empTrainDO.getRemake());
            }
            if (StringUtils.isNotBlank(empInfoVO.getChannelId())) {
                ChannelVO channelVO = channelService.selectById(empInfoVO.getChannelId(), tokenUser.getSiteId());
                empInfoVO.setChannelVO(channelVO);
            }
            // 奖惩记录
            List<EmpRewardPunishDO> empRewardPunishDOList =
                    empRewardPunishService.listByEmpId(empId, tokenUser.getSiteId());
            if (!CollectionUtils.isEmpty(empRewardPunishDOList)) {
                empRewardPunishDOList = empRewardPunishDOList.stream()
                        .sorted(Comparator.comparing(EmpRewardPunishDO::getGmtCreate)).collect(Collectors.toList());
                EmpRewardPunishDO empRewardPunishDO = empRewardPunishDOList.get(0);
                empInfoVO.setRewardPunish(empRewardPunishDO.getRewardPunish());
                empInfoVO.setRewardType(empRewardPunishDO.getRewardType());
                empInfoVO.setPunishType(empRewardPunishDO.getPunishType());
                empInfoVO.setHandleDate(empRewardPunishDO.getHandleDate());
                empInfoVO.setContent(empRewardPunishDO.getContent());
                empInfoVO.setAmount(empRewardPunishDO.getAmount());
                empInfoVO.setReason(empRewardPunishDO.getReason());
                empInfoVO.setRewardsRemark(empRewardPunishDO.getRemark());
            }
            companyId = empInfoVO.getCompanyId();
            empFieldDTOList = empInfoToFieldDTOList(empInfoVO, tokenUser, postTypeMap);
            empAdditionalFieldsDOList = empAdditionalFieldsService.selectByEmpId(empId, tokenUser.getSiteId());
        } else if (checkInPeopleVO != null) {
            empFieldDTOList = checkInToFieldDTOList(checkInPeopleVO, tokenUser);
            empAdditionalFieldsDOList = empAdditionalFieldsService.selectByCheckInId(empId, tokenUser.getSiteId());
            if (queryType == 1) {
                companyId = "site";
                moduleCode = CustomerModuleType.CHECK_IN.getValue();
            } else if (queryType == 3) {
                companyId = onboardingCompanyId;
                moduleCode = CustomerModuleType.WAIT_JOB.getValue();
            } else if (queryType == 4) {
                companyId = onboardingCompanyId;
                moduleCode = CustomerModuleType.ON_JOB.getValue();
            } else {
                throw new ParamException("查询员工类型有误");
            }
        } else {
            // 预登记
            throw new ParamException("员工已不存在，请刷新后重试");
        }
        Map<String, EmpFieldDTO> fieldCodeVOMap = empFieldDTOList.parallelStream()
                .collect(Collectors.toMap(EmpFieldDTO::getFieldCode, v -> v, (v1, v2) -> v1));
        // 查询模板
        CustomTemplateVO customTemplateVO = customTemplateService.selectOpenTemplate2(moduleCode, companyId, tokenUser);
        // 模板中系统字段
        List<CustomTemplateFieldVO> customTemplateFieldVOList = customTemplateVO.getCustomTemplateFieldVOList();
        for (CustomTemplateFieldVO customTemplateFieldVO : customTemplateFieldVOList) {
            EmpFieldDTO empFieldDTO = fieldCodeVOMap.get(customTemplateFieldVO.getFieldCode());
            if (empFieldDTO == null) {
                empFieldDTO = new EmpFieldDTO();
                empFieldDTO.setFieldName(customTemplateFieldVO.getFieldName());
                empFieldDTO.setFieldCode(customTemplateFieldVO.getFieldCode());
                empFieldDTO.setContent(null);
            }
            empFieldDTO.setSort(customTemplateFieldVO.getSort());
            allFieldDTOList.add(empFieldDTO);
        }
        // 试用期不在表单 有员工性质且为试用时需要展示
        // 员工状态
        EmpFieldDTO formalType = fieldCodeVOMap.get("formalType");
        // 试用期
        EmpFieldDTO probationDays = fieldCodeVOMap.get("probationDays");
        if (formalType != null && probationDays != null) {
            if (empInfoVO != null && empInfoVO.getFormalType() != null && empInfoVO.getFormalType() == 1) {
                probationDays.setSort(99999);
                allFieldDTOList.add(probationDays);
            }
            if (checkInPeopleVO != null && checkInPeopleVO.getFormalType() != null && checkInPeopleVO.getFormalType() == 1) {
                probationDays.setSort(99999);
                allFieldDTOList.add(probationDays);
            }
        }
        // 字段Id-员工输入内容
        Map<Long, String> fieldIdVOMap = empAdditionalFieldsDOList.parallelStream().filter(empAdditionalFieldsDO
                -> empAdditionalFieldsDO.getContent() != null).collect(Collectors.toMap(
                EmpAdditionalFieldsDO::getFieldId, EmpAdditionalFieldsDO::getContent, (v1, v2) -> v1));
        // 员工的自定义字段
        List<CompanyAdditionalFieldsDO> companyAdditionalFieldsDOList = companyAdditionalFieldsService
                .selectDOByIds(new ArrayList<>(fieldIdVOMap.keySet()), tokenUser.getSiteId());
        // 员工已有字段名称-Id Map
        Map<String, Long> fieldNameIdMap = companyAdditionalFieldsDOList.parallelStream()
                .collect(Collectors.toMap(CompanyAdditionalFieldsDO::getFieldName, BaseDO::getId));
        // 预登记的自定义字段需要转换成花名册自定义字段的Id
        Map<String, Long> empFieldNameIdMap = new HashMap<>();
        if (queryType == 1 && StringUtils.isNotBlank(onboardingCompanyId)) {
            //查询所有自定义字段
            List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsListVOList =
                    companyAdditionalFieldsService.selectByCompanyId2(onboardingCompanyId, null, tokenUser.getSiteId());
            empFieldNameIdMap = companyAdditionalFieldsListVOList.parallelStream()
                    .collect(Collectors.toMap(CompanyAdditionalFieldsListVO::getFieldName
                            , CompanyAdditionalFieldsListVO::getId, (v1, v2) -> v1));
        }
        // 模板中自定义字段
        List<CompanyAdditionalFieldsListVO> companyAdditionalFieldsList = customTemplateVO.getAdditionalFieldsListVOS();
        for (CompanyAdditionalFieldsListVO companyAdditionalFieldsListVO : companyAdditionalFieldsList) {
            Long fieldId = fieldNameIdMap.get(companyAdditionalFieldsListVO.getFieldName());
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName(companyAdditionalFieldsListVO.getFieldName());
            if (fieldId == null) {
                empFieldDTO.setContent(null);
            } else {
                if (companyAdditionalFieldsListVO.getFieldType() == 6) {
                    empFieldDTO.setKey(fieldIdVOMap.get(fieldId));
                    empFieldDTO.setContent(getPlace(fieldIdVOMap.get(fieldId)));
                } else {
                    empFieldDTO.setContent(fieldIdVOMap.get(fieldId));
                }
            }
            // 花名册中字段Id
            Long empField = empFieldNameIdMap.get(companyAdditionalFieldsListVO.getFieldName());
            if (empField == null) {
                empFieldDTO.setFieldCode(companyAdditionalFieldsListVO.getId() + "");
            } else {
                empFieldDTO.setFieldCode(empField + "");
            }
            empFieldDTO.setSort(companyAdditionalFieldsListVO.getSort());
            allFieldDTOList.add(empFieldDTO);
        }
        allFieldDTOList = allFieldDTOList.parallelStream().sorted(Comparator.comparing(EmpFieldDTO::getSort)).collect(Collectors.toList());
        return allFieldDTOList;
    }

    @Override
    public Map<String, Object> isExit(String siteId, String empInfoId, String idCard) {
        Map map = new HashMap();
        map.put("flag", false);
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", siteId)
                .andEqualTo("idCard", idCard)
                .andNotEqualTo("status", 4)
                .andNotEqualTo("id", empInfoId);
        List<EmpInfoDO> list = empInfoDAO.selectByExample(example);
        if (list != null && list.size() > 0) {
            List<String> companyIds = list.stream().map(EmpInfoDO::getCompanyId).collect(Collectors.toList());
            List<CompanyDO> companyDOList = companyService.selectByIds(companyIds, siteId);
            String msg = companyDOList.stream().map(CompanyDO::getName).collect(Collectors.joining(","));
            map.put("flag", true);
            map.put("msg", msg);
            return map;
        }
        return map;
    }

    @Override
    public void updateDict(DictItemDO dictItem, DictItemUpdateDTO dictItemUpdateDTO, TokenUser tokenUser) {
        EmpInfoDO empInfoDO = new EmpInfoDO();
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1223".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("contractSubject", dictItem.getDictItemValue());
            empInfoDO.setContractSubject(dictItemUpdateDTO.getDictItemValue());
        } else {
            return;
        }
        empInfoDAO.updateByExampleSelective(empInfoDO, example);
    }

    @Override
    public Integer selectDict(DictItemDO dictItem, TokenUser tokenUser) {
        Example example = new Example(EmpInfoDO.class);
        example.and()
                .andEqualTo("valid", true)
                .andEqualTo("siteId", tokenUser.getSiteId());
        if ("1223".equals(dictItem.getDictCode())) {
            example.and().andEqualTo("contractSubject", dictItem.getDictItemValue());
        } else {
            return 0;
        }
        return empInfoDAO.selectCountByExample(example);
    }

    @Override
    public void updatePhoneById(String userId, String phone) {
        EmpInfoDO empInfoDO = new EmpInfoDO();
        empInfoDO.setPhone(phone);

        Example example = new Example(EmpInfoDO.class);
        example.and().andEqualTo("userId", userId)
                .andEqualTo("valid", true);

        empInfoDAO.updateByExampleSelective(empInfoDO, example);
    }

    private List<EmpFieldDTO> empInfoToFieldDTOList(EmpInfoVO empInfoVO, TokenUser tokenUser, Map<String, String> postTypeMap) {
        if (empInfoVO == null) {
            throw new ParamException("花名册员工不存在");
        }
        List<EmpFieldDTO> empFieldDTOList = new ArrayList<>();
        if (StringUtils.isNotBlank(empInfoVO.getName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("姓名");
            empFieldDTO.setFieldCode("name");
            empFieldDTO.setContent(empInfoVO.getName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getIdCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("身份证号");
            empFieldDTO.setFieldCode("idCard");
            empFieldDTO.setContent(empInfoVO.getIdCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getPostType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作性质");
            empFieldDTO.setFieldCode("postType");
            empFieldDTO.setKey(empInfoVO.getPostType() + "");
//            PostType postType = PostType.find(empInfoVO.getPostType());
//            if (postType != null) {
//                empFieldDTO.setContent(postType.getDesc());
//                empFieldDTOList.add(empFieldDTO);
//            }
            empFieldDTO.setContent(postTypeMap.get(empFieldDTO.getKey()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getVerified() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("实名认证");
            empFieldDTO.setFieldCode("verified");
            if (empInfoVO.getVerified()) {
                empFieldDTO.setContent("是");
            } else {
                empFieldDTO.setContent("否");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getContractsStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("合同签署状态");
            empFieldDTO.setFieldCode("contractsStatus");
            empFieldDTO.setKey(empInfoVO.getContractsStatus() + "");
            ContractsStatus contractsStatus = ContractsStatus.find(empInfoVO.getContractsStatus());
            if (contractsStatus != null) {
                empFieldDTO.setContent(contractsStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getIsImprove() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("信息补充（必填项）");
            empFieldDTO.setFieldCode("isImprove");
            if (empInfoVO.getIsImprove()) {
                empFieldDTO.setContent("是");
            } else {
                empFieldDTO.setContent("否");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getJoinDate() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职日期");
            empFieldDTO.setFieldCode("joinDate");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getJoinDate()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getFormalType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("员工状态");
            empFieldDTO.setFieldCode("formalType");
            empFieldDTO.setKey(empInfoVO.getFormalType() + "");
            FormalTypeEnum formalTypeEnum = FormalTypeEnum.find(empInfoVO.getFormalType());
            if (formalTypeEnum != null) {
                empFieldDTO.setContent(formalTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getProbationDays() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("试用期");
            empFieldDTO.setFieldCode("probationDays");
            empFieldDTO.setContent(empInfoVO.getProbationDays() + "");
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("手机号");
            empFieldDTO.setFieldCode("phone");
            empFieldDTO.setContent(empInfoVO.getPhone());
            empFieldDTOList.add(empFieldDTO);
        } else {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("手机号");
            empFieldDTO.setFieldCode("phone");
            empFieldDTO.setContent("");
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getGender() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("性别");
            empFieldDTO.setFieldCode("gender");
            empFieldDTO.setKey(empInfoVO.getGender() + "");
            GenderEnum genderEnum = GenderEnum.find(empInfoVO.getGender());
            if (genderEnum != null) {
                empFieldDTO.setContent(genderEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getNumber())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工号");
            empFieldDTO.setFieldCode("number");
            empFieldDTO.setContent(empInfoVO.getNumber());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getPreJoinDep())) {
            List<String> depIds = Arrays.asList(empInfoVO.getPreJoinDep().split(","));
            List<DepInfoDO> depInfoDOList = depInfoService.selectByIds(depIds, tokenUser);
            if (!CollectionUtils.isEmpty(depInfoDOList)) {
                EmpFieldDTO empFieldDTO = new EmpFieldDTO();
                empFieldDTO.setFieldName("部门");
                empFieldDTO.setFieldCode("depName");
                empFieldDTO.setContent(depInfoDOList.parallelStream().map(DepInfoDO::getName).collect(Collectors.joining("，")));
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getBirthday())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("出生日期");
            empFieldDTO.setFieldCode("birthday");
            empFieldDTO.setContent(empInfoVO.getBirthday().replace(" 00:00:00", ""));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getEmpAge() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("年龄");
            empFieldDTO.setFieldCode("empAge");
            empFieldDTO.setContent(empInfoVO.getEmpAge() + "岁");
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getMaritalStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("婚姻状况");
            empFieldDTO.setFieldCode("maritalStatus");
            empFieldDTO.setKey(empInfoVO.getMaritalStatus() + "");
            EmpMaritalStatus empMaritalStatus = EmpMaritalStatus.find(empInfoVO.getMaritalStatus());
            if (empMaritalStatus != null) {
                empFieldDTO.setContent(empMaritalStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getBirthStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("生育状况");
            empFieldDTO.setFieldCode("birthStatus");
            empFieldDTO.setKey(empInfoVO.getBirthStatus() + "");
            EmpBirthStatus empBirthStatus = EmpBirthStatus.find(empInfoVO.getBirthStatus());
            if (empBirthStatus != null) {
                empFieldDTO.setContent(empBirthStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }

        }
        if (StringUtils.isNotBlank(empInfoVO.getNation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("民族");
            empFieldDTO.setFieldCode("nation");
            empFieldDTO.setContent(empInfoVO.getNation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getPoliticalStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("政治面貌");
            empFieldDTO.setFieldCode("politicalStatus");
            empFieldDTO.setKey(empInfoVO.getPoliticalStatus() + "");
            EmpPoliticalStatus empPoliticalStatus = EmpPoliticalStatus.find(empInfoVO.getPoliticalStatus());
            if (empPoliticalStatus != null) {
                empFieldDTO.setContent(empPoliticalStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getRegType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户口类型");
            empFieldDTO.setFieldCode("regType");
            empFieldDTO.setKey(empInfoVO.getRegType() + "");
            RegTypeEnum regTypeEnum = RegTypeEnum.find(empInfoVO.getRegType());
            if (regTypeEnum != null) {
                empFieldDTO.setContent(regTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getNativeLocation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户籍地址");
            empFieldDTO.setFieldCode("nativeLocation");
            empFieldDTO.setContent(empInfoVO.getNativeLocation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getBloodGroup() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("血型");
            empFieldDTO.setFieldCode("bloodGroup");
            empFieldDTO.setKey(empInfoVO.getBloodGroup() + "");
            BloodGroupEnum bloodGroupEnum = BloodGroupEnum.find(empInfoVO.getBloodGroup());
            if (bloodGroupEnum != null) {
                empFieldDTO.setContent(bloodGroupEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getEmail())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人邮箱");
            empFieldDTO.setFieldCode("email");
            empFieldDTO.setContent(empInfoVO.getEmail());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getCurrentLocation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("现居住地");
            empFieldDTO.setFieldCode("currentLocation");
            empFieldDTO.setContent(empInfoVO.getCurrentLocation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getHighestEducation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学历");
            empFieldDTO.setFieldCode("highestEducation");
            empFieldDTO.setContent(empInfoVO.getHighestEducation());
            empFieldDTOList.add(empFieldDTO);
        }
//        if (StringUtils.isNotBlank(empInfoVO.getDegreeType())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("学位");
//            empFieldDTO.setFieldCode("degreeType");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.getGraCollege())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("毕业院校");
//            empFieldDTO.setFieldCode("graCollege");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.getMajor())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("毕业专业");
//            empFieldDTO.setFieldCode("major");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.getTeaMethods())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("学习形式");
//            empFieldDTO.setFieldCode("teaMethods");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
        if (StringUtils.isNotBlank(empInfoVO.getFamilyName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("成员姓名(家庭成员)");
            empFieldDTO.setFieldCode("familyName");
            empFieldDTO.setContent(empInfoVO.getFamilyName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getFamilyPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系电话(家庭成员)");
            empFieldDTO.setFieldCode("familyPhone");
            empFieldDTO.setContent(empInfoVO.getFamilyPhone());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getFamilyRelation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("与我的关系(家庭成员)");
            empFieldDTO.setFieldCode("familyRelation");
            empFieldDTO.setContent(empInfoVO.getFamilyRelation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getFamilyWorkUnit())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作单位(家庭成员)");
            empFieldDTO.setFieldCode("familyWorkUnit");
            empFieldDTO.setContent(empInfoVO.getFamilyWorkUnit());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContactsName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系人姓名(紧急联系人)");
            empFieldDTO.setFieldCode("contactsName");
            empFieldDTO.setContent(empInfoVO.getContactsName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContactsPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系电话(紧急联系人)");
            empFieldDTO.setFieldCode("contactsPhone");
            empFieldDTO.setContent(empInfoVO.getContactsPhone());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContactsRelation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("与我的关系(紧急联系人)");
            empFieldDTO.setFieldCode("contactsRelation");
            empFieldDTO.setContent(empInfoVO.getContactsRelation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContactsAddress())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系人地址(紧急联系人)");
            empFieldDTO.setFieldCode("contactsAddress");
            empFieldDTO.setContent(empInfoVO.getContactsAddress());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getEducation() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学历");
            empFieldDTO.setFieldCode("education");
            empFieldDTO.setKey(empInfoVO.getEducation() + "");
            EducationLevelEnum educationLevelEnum = EducationLevelEnum.find(empInfoVO.getEducation());
            if (educationLevelEnum != null) {
                empFieldDTO.setContent(educationLevelEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getGraCollege())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("毕业院校");
            empFieldDTO.setFieldCode("graCollege");
            empFieldDTO.setContent(empInfoVO.getGraCollege());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getMajor())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("毕业专业");
            empFieldDTO.setFieldCode("major");
            empFieldDTO.setContent(empInfoVO.getMajor());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getStartTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("教育开始时间");
            empFieldDTO.setFieldCode("startTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getStartTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getEndTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("教育结束时间");
            empFieldDTO.setFieldCode("endTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getEndTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTeaMethods())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学习形式");
            empFieldDTO.setFieldCode("teaMethods");
            empFieldDTO.setKey(empInfoVO.getTeaMethods() + "");
            TeachMethod teachMethod = TeachMethod.find(Integer.parseInt(empInfoVO.getTeaMethods()));
            if (teachMethod != null) {
                empFieldDTO.setContent(teachMethod.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getGraCerNumber())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("毕业证书编号");
            empFieldDTO.setFieldCode("graCerNumber");
            empFieldDTO.setContent(empInfoVO.getGraCerNumber());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getDegreeType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学位类型");
            empFieldDTO.setFieldCode("degreeType");
            empFieldDTO.setKey(empInfoVO.getDegreeType() + "");
            EmpDegreeType empDegreeType = EmpDegreeType.find(empInfoVO.getDegreeType());
            if (empDegreeType != null) {
                empFieldDTO.setContent(empDegreeType.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getDegreeName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学位名称");
            empFieldDTO.setFieldCode("degreeName");
            empFieldDTO.setContent(empInfoVO.getDegreeName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getDegreeNumber())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学位证书编号");
            empFieldDTO.setFieldCode("degreeNumber");
            empFieldDTO.setContent(empInfoVO.getDegreeNumber());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getEducationRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("教育备注");
            empFieldDTO.setFieldCode("educationRemark");
            empFieldDTO.setContent(empInfoVO.getEducationRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getCompany())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作单位");
            empFieldDTO.setFieldCode("company");
            empFieldDTO.setContent(empInfoVO.getCompany());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getPosition())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("职务");
            empFieldDTO.setFieldCode("position");
            empFieldDTO.setContent(empInfoVO.getPosition());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getWorkStartTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作开始时间");
            empFieldDTO.setFieldCode("workStartTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getWorkStartTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getWorkEndTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作结束时间");
            empFieldDTO.setFieldCode("workEndTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getWorkEndTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getWitName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("证明人");
            empFieldDTO.setFieldCode("witName");
            empFieldDTO.setContent(empInfoVO.getWitName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getWitPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("证明人联系电话");
            empFieldDTO.setFieldCode("witPhone");
            empFieldDTO.setContent(empInfoVO.getWitPhone());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getLeaveReason())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职原因");
            empFieldDTO.setFieldCode("leaveReason");
            empFieldDTO.setContent(empInfoVO.getLeaveReason());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getLeaveSalary() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职薪资");
            empFieldDTO.setFieldCode("leaveSalary");
            empFieldDTO.setContent(empInfoVO.getLeaveSalary() + "");
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getWorkRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作备注");
            empFieldDTO.setFieldCode("workRemark");
            empFieldDTO.setContent(empInfoVO.getWorkRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTrainCourse())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训名称");
            empFieldDTO.setFieldCode("trainCourse");
            empFieldDTO.setContent(empInfoVO.getTrainCourse());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTrainOrgName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训单位");
            empFieldDTO.setFieldCode("trainOrgName");
            empFieldDTO.setContent(empInfoVO.getTrainOrgName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getTrainStartTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训开始时间");
            empFieldDTO.setFieldCode("trainStartTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getTrainStartTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getTrainEndTime() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训结束时间");
            empFieldDTO.setFieldCode("trainEndTime");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getTrainEndTime()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAssessResult())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训成绩");
            empFieldDTO.setFieldCode("assessResult");
            empFieldDTO.setContent(empInfoVO.getAssessResult());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTrainCerName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训证书名称");
            empFieldDTO.setFieldCode("trainCerName");
            empFieldDTO.setContent(empInfoVO.getTrainCerName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTrainCerNumber())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训证书编号");
            empFieldDTO.setFieldCode("trainCerNumber");
            empFieldDTO.setContent(empInfoVO.getTrainCerNumber());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("培训备注");
            empFieldDTO.setFieldCode("remake");
            empFieldDTO.setContent(empInfoVO.getRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getIssuedBy())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("签发机关");
            empFieldDTO.setFieldCode("issuedBy");
            empFieldDTO.setContent(empInfoVO.getIssuedBy());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getCardStartDate())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("开始期限");
            empFieldDTO.setFieldCode("cardStartDate");
            empFieldDTO.setContent(empInfoVO.getCardStartDate());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getCardEndDate())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("结束期限");
            empFieldDTO.setFieldCode("cardEndDate");
            empFieldDTO.setContent(empInfoVO.getCardEndDate());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getChannelVO() != null && StringUtils.isNotBlank(empInfoVO.getChannelVO().getName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("渠道来源");
            empFieldDTO.setFieldCode("channelId");
            empFieldDTO.setContent(empInfoVO.getChannelVO().getName());
            empFieldDTO.setKey(empInfoVO.getChannelVO().getId());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getBankCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡卡号");
            empFieldDTO.setFieldCode("bankCard");
            empFieldDTO.setContent(empInfoVO.getBankCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getBankName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("银行名称");
            empFieldDTO.setFieldCode("bankName");
            empFieldDTO.setContent(empInfoVO.getBankName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getBankPlace())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡开户城市");
            empFieldDTO.setFieldCode("bankPlace");
            String place = getPlace(empInfoVO.getBankPlace());
            empFieldDTO.setContent(place);
            empFieldDTO.setKey(empInfoVO.getBankPlace());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getBankCardBranch())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡开户支行");
            empFieldDTO.setFieldCode("bankCardBranch");
            empFieldDTO.setContent(empInfoVO.getBankCardBranch());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAlipayAccount())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("支付宝账号");
            empFieldDTO.setFieldCode("alipayAccount");
            empFieldDTO.setContent(empInfoVO.getAlipayAccount());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getIsFirstSoc() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("是否首次缴纳社保");
            empFieldDTO.setFieldCode("isFirstSoc");
            if (empInfoVO.getIsFirstSoc()) {
                empFieldDTO.setContent("是");
                empFieldDTO.setKey("true");
            } else {
                empFieldDTO.setContent("否");
                empFieldDTO.setKey("false");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getSocCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人社保卡号");
            empFieldDTO.setFieldCode("socCard");
            empFieldDTO.setContent(empInfoVO.getSocCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getIsFirstPf() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("是否首次缴纳公积金");
            empFieldDTO.setFieldCode("isFirstPf");
            if (empInfoVO.getIsFirstPf()) {
                empFieldDTO.setContent("是");
                empFieldDTO.setKey("true");
            } else {
                empFieldDTO.setContent("否");
                empFieldDTO.setKey("false");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getPfCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人公积金账号");
            empFieldDTO.setFieldCode("pfCard");
            empFieldDTO.setContent(empInfoVO.getPfCard());
            empFieldDTOList.add(empFieldDTO);
        }
//        if (StringUtils.isNotBlank(empInfoVO.getContractType())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("合同类型");
//            empFieldDTO.setFieldCode("contractType");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.get)) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("合同开始时间");
//            empFieldDTO.setFieldCode("contractStartTime");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.get)) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("合同结束时间");
//            empFieldDTO.setFieldCode("contractEndTime");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
//        if (StringUtils.isNotBlank(empInfoVO.get)) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("合同期限");
//            empFieldDTO.setFieldCode("contactsTerm");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
        if (StringUtils.isNotBlank(empInfoVO.getRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("备注");
            empFieldDTO.setFieldCode("remark");
            empFieldDTO.setContent(empInfoVO.getRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getTag())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("标签");
            empFieldDTO.setFieldCode("tag");
            empFieldDTO.setContent(empInfoVO.getTag());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getWorkCity())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作地点");
            empFieldDTO.setFieldCode("workCity");
            empFieldDTO.setContent(empInfoVO.getWorkCity());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getJoinCityName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职城市");
            empFieldDTO.setFieldCode("joinCityName");
            empFieldDTO.setContent(getPlace(empInfoVO.getJoinCityName()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContractSubject())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("签约主体");
            empFieldDTO.setFieldCode("contractSubject");
            empFieldDTO.setContent(empInfoVO.getContractSubject());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getArchivesNumber())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("档案编号");
            empFieldDTO.setFieldCode("archivesNumber");
            empFieldDTO.setContent(empInfoVO.getArchivesNumber());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getArchivesRemake())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("档案备注");
            empFieldDTO.setFieldCode("archivesRemake");
            empFieldDTO.setContent(empInfoVO.getArchivesRemake());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getRewardPunish() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖励/惩罚");
            empFieldDTO.setFieldCode("rewardPunish");
            empFieldDTO.setKey(empInfoVO.getRewardPunish() + "");
            RewardPunishEnum rewardPunishEnum = RewardPunishEnum.find(empInfoVO.getRewardPunish());
            if (rewardPunishEnum != null) {
                empFieldDTO.setContent(rewardPunishEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getArchivesRemake())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("档案备注");
            empFieldDTO.setFieldCode("archivesRemake");
            empFieldDTO.setContent(empInfoVO.getArchivesRemake());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getRewardType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖励类别");
            empFieldDTO.setFieldCode("rewardType");
            empFieldDTO.setKey(empInfoVO.getRewardType() + "");
            RewardTypeEnum rewardTypeEnum = RewardTypeEnum.find(empInfoVO.getRewardType());
            if (rewardTypeEnum != null) {
                empFieldDTO.setContent(rewardTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getPunishType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("惩罚类别");
            empFieldDTO.setFieldCode("punishType");
            empFieldDTO.setKey(empInfoVO.getPunishType() + "");
            PunishTypeEnum punishTypeEnum = PunishTypeEnum.find(empInfoVO.getPunishType());
            if (punishTypeEnum != null) {
                empFieldDTO.setContent(punishTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (empInfoVO.getHandleDate() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖惩时间");
            empFieldDTO.setFieldCode("handleDate");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getHandleDate()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getContent())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖惩内容");
            empFieldDTO.setFieldCode("content");
            empFieldDTO.setContent(empInfoVO.getContent());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getAmount() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖惩金额");
            empFieldDTO.setFieldCode("amount");
            empFieldDTO.setContent(empInfoVO.getAmount() + "");
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getReason())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖惩原因");
            empFieldDTO.setFieldCode("reason");
            empFieldDTO.setContent(empInfoVO.getReason());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getRewardsRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("奖惩备注");
            empFieldDTO.setFieldCode("rewardsRemark");
            empFieldDTO.setContent(empInfoVO.getRewardsRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getRetirementAge() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("退休年龄");
            empFieldDTO.setFieldCode("retirementAge");
            empFieldDTO.setContent(empInfoVO.getRetirementAge() + "");
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getRetirementStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("是否已退休");
            empFieldDTO.setFieldCode("retirementStatus");
            if (empInfoVO.getRetirementStatus()) {
                empFieldDTO.setContent("是");
                empFieldDTO.setKey("true");
            } else {
                empFieldDTO.setContent("否");
                empFieldDTO.setKey("false");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (empInfoVO.getRetirementDate() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("退休日期");
            empFieldDTO.setFieldCode("retirementDate");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(empInfoVO.getRetirementDate()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getRetirementRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("退休备注");
            empFieldDTO.setFieldCode("retirementRemark");
            empFieldDTO.setContent(empInfoVO.getRetirementRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getPreJoinPosition())) {
            List<String> positionIds = Arrays.asList(empInfoVO.getPreJoinPosition().split(","));
            List<PositionInfoDO> positionInfoDOList = positionInfoService.selectByIdList(positionIds, tokenUser);
            if (!CollectionUtils.isEmpty(positionInfoDOList)) {
                EmpFieldDTO empFieldDTO = new EmpFieldDTO();
                empFieldDTO.setFieldName("岗位");
                empFieldDTO.setFieldCode("positionName");
                empFieldDTO.setContent(positionInfoDOList.parallelStream().map(PositionInfoDO::getName).collect(Collectors.joining("，")));
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexPersonPhoto())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人证件照");
            empFieldDTO.setFieldCode("annexPersonPhoto");
            empFieldDTO.setContent(empInfoVO.getAnnexPersonPhoto());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexIdCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("身份证原件照片");
            empFieldDTO.setFieldCode("annexIdCard");
            empFieldDTO.setContent(empInfoVO.getAnnexIdCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexDegree())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学历证明");
            empFieldDTO.setFieldCode("annexDegree");
            empFieldDTO.setContent(empInfoVO.getAnnexDegree());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexHousehold())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户口本照片");
            empFieldDTO.setFieldCode("annexHousehold");
            empFieldDTO.setContent(empInfoVO.getAnnexHousehold());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexSalaryCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资银行卡");
            empFieldDTO.setFieldCode("annexSalaryCard");
            empFieldDTO.setContent(empInfoVO.getAnnexSalaryCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexSocCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("社保卡");
            empFieldDTO.setFieldCode("annexSocCard");
            empFieldDTO.setContent(empInfoVO.getAnnexSocCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexPfCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("公积金卡");
            empFieldDTO.setFieldCode("annexPfCard");
            empFieldDTO.setContent(empInfoVO.getAnnexPfCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexPractising())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("职业资格证书");
            empFieldDTO.setFieldCode("annexPractising");
            empFieldDTO.setContent(empInfoVO.getAnnexPractising());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexReward())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("获奖证书");
            empFieldDTO.setFieldCode("annexReward");
            empFieldDTO.setContent(empInfoVO.getAnnexReward());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexNoCriminal())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("无犯罪记录证明");
            empFieldDTO.setFieldCode("annexNoCriminal");
            empFieldDTO.setContent(empInfoVO.getAnnexNoCriminal());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLaborContract())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("劳动合同");
            empFieldDTO.setFieldCode("annexLaborContract");
            empFieldDTO.setContent(empInfoVO.getAnnexLaborContract());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLastLeaveCert())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("上家公司离职证明");
            empFieldDTO.setFieldCode("annexLastLeaveCert");
            empFieldDTO.setContent(empInfoVO.getAnnexLastLeaveCert());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexOnbCheckup())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职体检单");
            empFieldDTO.setFieldCode("annexOnbCheckup");
            empFieldDTO.setContent(empInfoVO.getAnnexOnbCheckup());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexOnbResume())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职简历");
            empFieldDTO.setFieldCode("annexOnbResume");
            empFieldDTO.setContent(empInfoVO.getAnnexOnbResume());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexWorkApply())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作申请表");
            empFieldDTO.setFieldCode("annexWorkApply");
            empFieldDTO.setContent(empInfoVO.getAnnexWorkApply());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexAdjustNotice())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("调薪通知单");
            empFieldDTO.setFieldCode("annexAdjustNotice");
            empFieldDTO.setContent(empInfoVO.getAnnexAdjustNotice());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexPersonalChange())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("人事异动申请表");
            empFieldDTO.setFieldCode("annexPersonalChange");
            empFieldDTO.setContent(empInfoVO.getAnnexPersonalChange());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexSocTransfer())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("社会保险转移单");
            empFieldDTO.setFieldCode("annexSocTransfer");
            empFieldDTO.setContent(empInfoVO.getAnnexSocTransfer());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexPerformanceReport())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("效绩考核结果报告");
            empFieldDTO.setFieldCode("annexPerformanceReport");
            empFieldDTO.setContent(empInfoVO.getAnnexPerformanceReport());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexNoPregnant())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("女职工未孕证明");
            empFieldDTO.setFieldCode("annexNoPregnant");
            empFieldDTO.setContent(empInfoVO.getAnnexNoPregnant());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLeaveAppro())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职审批");
            empFieldDTO.setFieldCode("annexLeaveAppro");
            empFieldDTO.setContent(empInfoVO.getAnnexLeaveAppro());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLeaveCert())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职证明");
            empFieldDTO.setFieldCode("annexLeaveCert");
            empFieldDTO.setContent(empInfoVO.getAnnexLeaveCert());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLeaveApply())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职申请表");
            empFieldDTO.setFieldCode("annexLeaveApply");
            empFieldDTO.setContent(empInfoVO.getAnnexLeaveApply());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexHandoverTable())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作交接表");
            empFieldDTO.setFieldCode("annexHandoverTable");
            empFieldDTO.setContent(empInfoVO.getAnnexHandoverTable());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(empInfoVO.getAnnexLeaving())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("前公司解除劳动关系证明");
            empFieldDTO.setFieldCode("annexLeaving");
            empFieldDTO.setContent(empInfoVO.getAnnexLeaving());
            empFieldDTOList.add(empFieldDTO);
        }
        return empFieldDTOList;
    }

    /**
     * 根据地区code转换具体地址
     *
     * @param placeCode 地区code
     * @return 具体地址
     */
    private String getPlace(String placeCode) {
        if (StringUtils.isBlank(placeCode)) {
            return "";
        }
        String bankPlace = placeCode.replaceAll("\\[", "");
        bankPlace = bankPlace.replaceAll("]", "");
        // 查询城市信息
        String[] split = bankPlace.split(",");
        List<String> areaList = new ArrayList<>();
        for (String areaId : split) {
            String areaName;
            if (areaId.matches("[0-9]+")) {
                areaName = adminProviderService.selectAreaById(areaId);
            } else {
                areaName = areaId.replaceAll("/", "-");
            }
            areaList.add(areaName);
        }
        return areaList.parallelStream().collect(Collectors.joining("/"));
    }

    /**
     * 预登记人员转List
     *
     * @param checkInPeopleVO 预登记人员
     * @param tokenUser       登录用户
     * @return list
     */
    private List<EmpFieldDTO> checkInToFieldDTOList(CheckInPeopleVO checkInPeopleVO, TokenUser tokenUser) {
        if (checkInPeopleVO == null) {
            throw new ParamException("预登记员工不存在");
        }
        List<EmpFieldDTO> empFieldDTOList = new ArrayList<>();
        if (StringUtils.isNotBlank(checkInPeopleVO.getName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("姓名");
            empFieldDTO.setFieldCode("name");
            empFieldDTO.setContent(checkInPeopleVO.getName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getIdcard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("身份证号");
            empFieldDTO.setFieldCode("idcard");
            empFieldDTO.setContent(checkInPeopleVO.getIdcard());
            empFieldDTOList.add(empFieldDTO);
            // 兼容花名册身份证号字段
            EmpFieldDTO empFieldDTO1 = new EmpFieldDTO();
            empFieldDTO1.setFieldName("身份证号");
            empFieldDTO1.setFieldCode("idCard");
            empFieldDTO1.setContent(checkInPeopleVO.getIdcard());
            empFieldDTOList.add(empFieldDTO1);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("手机号");
            empFieldDTO.setFieldCode("phone");
            empFieldDTO.setContent(checkInPeopleVO.getPhone());
            empFieldDTOList.add(empFieldDTO);
        } else {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("手机号");
            empFieldDTO.setFieldCode("phone");
            empFieldDTO.setContent("");
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getChannelId())) {
            ChannelVO channelVO = channelService.selectById(checkInPeopleVO.getChannelId(), tokenUser.getSiteId());
            if (channelVO != null) {
                EmpFieldDTO empFieldDTO = new EmpFieldDTO();
                empFieldDTO.setFieldName("渠道来源");
                empFieldDTO.setFieldCode("channelId");
                empFieldDTO.setContent(channelVO.getName());
                empFieldDTO.setKey(channelVO.getId());
                empFieldDTOList.add(empFieldDTO);
            }
        }
//        if (StringUtils.isNotBlank(checkInPeopleVO.getCompanyName())) {
//            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
//            empFieldDTO.setFieldName("用工单位");
//            empFieldDTO.setFieldCode("companyName");
//            empFieldDTO.setContent();
//            empFieldDTOList.add(empFieldDTO);
//        }
        if (checkInPeopleVO.getStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("人员状态");
            empFieldDTO.setFieldCode("status");
            switch (checkInPeopleVO.getStatus()) {
                case 1:
                    empFieldDTO.setContent("已接到");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 2:
                    empFieldDTO.setContent("已安排");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 3:
                    empFieldDTO.setContent("已面试");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 4:
                    empFieldDTO.setContent("已入职");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 5:
                    empFieldDTO.setContent("已离职");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 6:
                    empFieldDTO.setContent("待入职");
                    empFieldDTOList.add(empFieldDTO);
                    break;
                case 7:
                    empFieldDTO.setContent("未到岗");
                    empFieldDTOList.add(empFieldDTO);
                    break;
            }
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getRemark())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("备注");
            empFieldDTO.setFieldCode("remark");
            empFieldDTO.setContent(checkInPeopleVO.getRemark());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getNation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("民族");
            empFieldDTO.setFieldCode("nation");
            empFieldDTO.setContent(checkInPeopleVO.getNation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getBirthday())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("出生日期");
            empFieldDTO.setFieldCode("birthday");
            empFieldDTO.setContent(checkInPeopleVO.getBirthday().replace(" 00:00:00", ""));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getNativeLocation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户籍住址");
            empFieldDTO.setFieldCode("nativeLocation");
            empFieldDTO.setContent(checkInPeopleVO.getNativeLocation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getIssuedBy())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("签发机关");
            empFieldDTO.setFieldCode("issuedBy");
            empFieldDTO.setContent(checkInPeopleVO.getIssuedBy());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getStartDate())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("开始时间");
            empFieldDTO.setFieldCode("startDate");
            empFieldDTO.setContent(checkInPeopleVO.getStartDate().replace(" 00:00:00", ""));
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getEndDate())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("结束时间");
            empFieldDTO.setFieldCode("endDate");
            empFieldDTO.setContent(checkInPeopleVO.getEndDate());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getPhoto())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("身份证照上传");
            empFieldDTO.setFieldCode("photo");
            empFieldDTO.setContent(checkInPeopleVO.getPhoto());
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getGmtCreate() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("登记时间");
            empFieldDTO.setFieldCode("gmtCreate");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(checkInPeopleVO.getGmtCreate()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getPostType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作性质");
            empFieldDTO.setFieldCode("postType");
            empFieldDTO.setKey(checkInPeopleVO.getPostType() + "");
            PostType postType = PostType.find(checkInPeopleVO.getPostType());
            if (postType != null) {
                empFieldDTO.setContent(postType.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (checkInPeopleVO.getJoinDate() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职日期");
            empFieldDTO.setFieldCode("joinDate");
            SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
            empFieldDTO.setContent(formatter.format(checkInPeopleVO.getJoinDate()));
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getFormalType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("员工状态");
            empFieldDTO.setFieldCode("formalType");
            empFieldDTO.setKey(checkInPeopleVO.getFormalType() + "");
            FormalTypeEnum formalTypeEnum = FormalTypeEnum.find(checkInPeopleVO.getFormalType());
            if (formalTypeEnum != null) {
                empFieldDTO.setContent(formalTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (checkInPeopleVO.getProbationDays() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("试用期");
            empFieldDTO.setFieldCode("probationDays");
            empFieldDTO.setContent(checkInPeopleVO.getProbationDays() + "");
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getMaritalStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("婚姻状况");
            empFieldDTO.setFieldCode("maritalStatus");
            empFieldDTO.setKey(checkInPeopleVO.getMaritalStatus() + "");
            EmpMaritalStatus empMaritalStatus = EmpMaritalStatus.find(checkInPeopleVO.getMaritalStatus());
            if (empMaritalStatus != null) {
                empFieldDTO.setContent(empMaritalStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (checkInPeopleVO.getBirthStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("生育状况");
            empFieldDTO.setFieldCode("birthStatus");
            empFieldDTO.setKey(checkInPeopleVO.getBirthStatus() + "");
            EmpBirthStatus empBirthStatus = EmpBirthStatus.find(checkInPeopleVO.getBirthStatus());
            if (empBirthStatus != null) {
                empFieldDTO.setContent(empBirthStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (checkInPeopleVO.getPoliticalStatus() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("政治面貌");
            empFieldDTO.setFieldCode("politicalStatus");
            empFieldDTO.setKey(checkInPeopleVO.getPoliticalStatus() + "");
            EmpPoliticalStatus empPoliticalStatus = EmpPoliticalStatus.find(checkInPeopleVO.getPoliticalStatus());
            if (empPoliticalStatus != null) {
                empFieldDTO.setContent(empPoliticalStatus.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (checkInPeopleVO.getRegType() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户口类型");
            empFieldDTO.setFieldCode("regType");
            empFieldDTO.setKey(checkInPeopleVO.getRegType() + "");
            RegTypeEnum regTypeEnum = RegTypeEnum.find(checkInPeopleVO.getRegType());
            if (regTypeEnum != null) {
                empFieldDTO.setContent(regTypeEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getNativeLocation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户籍地址");
            empFieldDTO.setFieldCode("nativeLocation");
            empFieldDTO.setContent(checkInPeopleVO.getNativeLocation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getBloodGroup() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("血型");
            empFieldDTO.setFieldCode("bloodGroup");
            empFieldDTO.setKey(checkInPeopleVO.getBloodGroup() + "");
            BloodGroupEnum bloodGroupEnum = BloodGroupEnum.find(checkInPeopleVO.getBloodGroup());
            if (bloodGroupEnum != null) {
                empFieldDTO.setContent(bloodGroupEnum.getDesc());
                empFieldDTOList.add(empFieldDTO);
            }
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getEmail())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人邮箱");
            empFieldDTO.setFieldCode("email");
            empFieldDTO.setContent(checkInPeopleVO.getEmail());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getCurrentLocation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("现居住地");
            empFieldDTO.setFieldCode("currentLocation");
            empFieldDTO.setContent(checkInPeopleVO.getCurrentLocation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexPersonPhoto())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人证件照");
            empFieldDTO.setFieldCode("annexPersonPhoto");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexPersonPhoto());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexIdCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("身份证原件照片");
            empFieldDTO.setFieldCode("annexIdCard");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexIdCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexDegree())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("学历证明");
            empFieldDTO.setFieldCode("annexDegree");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexDegree());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexHousehold())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("户口本照片");
            empFieldDTO.setFieldCode("annexHousehold");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexHousehold());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexSalaryCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资银行卡");
            empFieldDTO.setFieldCode("annexSalaryCard");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexSalaryCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexSocCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("社保卡");
            empFieldDTO.setFieldCode("annexSocCard");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexSocCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexPfCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("公积金卡");
            empFieldDTO.setFieldCode("annexPfCard");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexPfCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexPractising())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("职业资格证书");
            empFieldDTO.setFieldCode("annexPractising");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexPractising());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexReward())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("获奖证书");
            empFieldDTO.setFieldCode("annexReward");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexReward());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexNoCriminal())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("无犯罪记录证明");
            empFieldDTO.setFieldCode("annexNoCriminal");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexNoCriminal());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLaborContract())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("劳动合同");
            empFieldDTO.setFieldCode("annexLaborContract");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLaborContract());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLastLeaveCert())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("上家公司离职证明");
            empFieldDTO.setFieldCode("annexLastLeaveCert");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLastLeaveCert());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexOnbCheckup())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职体检单");
            empFieldDTO.setFieldCode("annexOnbCheckup");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexOnbCheckup());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexOnbResume())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("入职简历");
            empFieldDTO.setFieldCode("annexOnbResume");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexOnbResume());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexWorkApply())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作申请表");
            empFieldDTO.setFieldCode("annexWorkApply");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexWorkApply());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexAdjustNotice())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("调薪通知单");
            empFieldDTO.setFieldCode("annexAdjustNotice");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexAdjustNotice());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexPersonalChange())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("人事异动申请表");
            empFieldDTO.setFieldCode("annexPersonalChange");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexPersonalChange());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexSocTransfer())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("社会保险转移单");
            empFieldDTO.setFieldCode("annexSocTransfer");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexSocTransfer());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexPerformanceReport())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("效绩考核结果报告");
            empFieldDTO.setFieldCode("annexPerformanceReport");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexPerformanceReport());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexNoPregnant())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("女职工未孕证明");
            empFieldDTO.setFieldCode("annexNoPregnant");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexNoPregnant());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getFamilyName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("成员姓名");
            empFieldDTO.setFieldCode("familyName");
            empFieldDTO.setContent(checkInPeopleVO.getFamilyName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getFamilyPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系电话（家庭成员）");
            empFieldDTO.setFieldCode("familyPhone");
            empFieldDTO.setContent(checkInPeopleVO.getFamilyPhone());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getFamilyRelation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("与我的关系（家庭成员）");
            empFieldDTO.setFieldCode("familyRelation");
            empFieldDTO.setContent(checkInPeopleVO.getFamilyRelation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getContactsName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系人姓名");
            empFieldDTO.setFieldCode("contactsName");
            empFieldDTO.setContent(checkInPeopleVO.getContactsName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLeaveAppro())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职审批");
            empFieldDTO.setFieldCode("annexLeaveAppro");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLeaveAppro());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLeaveCert())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职证明");
            empFieldDTO.setFieldCode("annexLeaveCert");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLeaveCert());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getFamilyWorkUnit())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作单位");
            empFieldDTO.setFieldCode("familyWorkUnit");
            empFieldDTO.setContent(checkInPeopleVO.getFamilyWorkUnit());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLeaveApply())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("离职申请表");
            empFieldDTO.setFieldCode("annexLeaveApply");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLeaveApply());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexHandoverTable())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工作交接表");
            empFieldDTO.setFieldCode("annexHandoverTable");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexHandoverTable());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getContactsPhone())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系电话（紧急联系人）");
            empFieldDTO.setFieldCode("contactsPhone");
            empFieldDTO.setContent(checkInPeopleVO.getContactsPhone());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getAnnexLeaving())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("前公司解除劳动关系证明");
            empFieldDTO.setFieldCode("annexLeaving");
            empFieldDTO.setContent(checkInPeopleVO.getAnnexLeaving());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getContactsRelation())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("与我的关系（紧急联系人）");
            empFieldDTO.setFieldCode("contactsRelation");
            empFieldDTO.setContent(checkInPeopleVO.getContactsRelation());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getContactsAddress())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("联系人地址");
            empFieldDTO.setFieldCode("contactsAddress");
            empFieldDTO.setContent(checkInPeopleVO.getContactsAddress());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getBankCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡卡号");
            empFieldDTO.setFieldCode("bankCard");
            empFieldDTO.setContent(checkInPeopleVO.getBankCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getBankName())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("银行名称");
            empFieldDTO.setFieldCode("bankName");
            empFieldDTO.setContent(checkInPeopleVO.getBankName());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getBankPlace())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡开户城市");
            empFieldDTO.setFieldCode("bankPlace");

            empFieldDTO.setContent(getPlace(checkInPeopleVO.getBankPlace()));
            empFieldDTO.setKey(checkInPeopleVO.getBankPlace());
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getBankCardBranch())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("工资卡开户支行");
            empFieldDTO.setFieldCode("bankCardBranch");
            empFieldDTO.setContent(checkInPeopleVO.getBankCardBranch());
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getIsFirstSoc() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("是否首次缴纳社保");
            empFieldDTO.setFieldCode("isFirstSoc");
            if (checkInPeopleVO.getIsFirstSoc()) {
                empFieldDTO.setContent("是");
                empFieldDTO.setKey("true");
            } else {
                empFieldDTO.setContent("否");
                empFieldDTO.setKey("false");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getSocCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人社保卡号");
            empFieldDTO.setFieldCode("socCard");
            empFieldDTO.setContent(checkInPeopleVO.getSocCard());
            empFieldDTOList.add(empFieldDTO);
        }
        if (checkInPeopleVO.getIsFirstPf() != null) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("是否首次缴纳公积金");
            empFieldDTO.setFieldCode("isFirstPf");
            if (checkInPeopleVO.getIsFirstPf()) {
                empFieldDTO.setContent("是");
                empFieldDTO.setKey("true");
            } else {
                empFieldDTO.setContent("否");
                empFieldDTO.setKey("false");
            }
            empFieldDTOList.add(empFieldDTO);
        }
        if (StringUtils.isNotBlank(checkInPeopleVO.getPfCard())) {
            EmpFieldDTO empFieldDTO = new EmpFieldDTO();
            empFieldDTO.setFieldName("个人公积金账号");
            empFieldDTO.setFieldCode("pfCard");
            empFieldDTO.setContent(checkInPeopleVO.getPfCard());
            empFieldDTOList.add(empFieldDTO);
        }
        return empFieldDTOList;
    }

}





